/**
 @file sys_usw_peri.c

 @date 2009-10-19

 @version v2.0

 The file define APIs of chip of sys layer
*/
/****************************************************************************
 *
 * Header Files
 *
 ****************************************************************************/
#include "sal.h"
#include "dal.h"
#include "ctc_error.h"
#include "ctc_register.h"
#include "sys_usw_peri.h"
#include "sys_usw_chip_global.h"
#include "sys_usw_mac.h"
#include "sys_usw_dmps.h"
#include "sys_usw_chip.h"
#include "sys_usw_datapath.h"
#include "sys_usw_common.h"
#include "sys_usw_interrupt.h"
#include "sys_usw_dma.h"
#include "sys_usw_port.h"

#include "drv_api.h"
#define SYS_USW_PERI_MAX_DRV_CAP 15
#define SYS_TM_PERI_MAX_DRV_CAP 7
#define SYS_AT_PERI_MAX_DRV_CAP 3

/****************************************************************************
 *
 * Global and static
 *
 *****************************************************************************/
sys_peri_master_t* p_usw_peri_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};

extern dal_op_t g_dal_op;
int32
sys_usw_peri_set_phy_scan_cfg(uint8 lchip);
extern int32
_sys_usw_mac_get_cl37_an_remote_status(uint8 lchip, uint16 lport, uint32 auto_neg_mode, uint32* p_speed, uint32* p_link);

/****************************************************************************
 *
 * Function
 *
 *****************************************************************************/
/**
 @brief The function is to initialize the chip module and set the local chip number of the linecard
*/
int32
sys_usw_peri_init(uint8 lchip, uint8 lchip_num)
{
    int32 ret;
#if 0
    if (lchip_num > SYS_USW_MAX_LOCAL_CHIP_NUM)
    {
        return CTC_E_INVALID_CHIP_NUM;
    }
#endif
    SYS_VCHIP_MASTER_INIT_GLOBAL(lchip, p_usw_peri_master);
    p_usw_peri_master[lchip] = (sys_peri_master_t*)mem_malloc(MEM_SYSTEM_MODULE, sizeof(sys_peri_master_t));

    if (NULL == p_usw_peri_master[lchip])
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
		return CTC_E_NO_MEMORY;
    }
    sal_memset(p_usw_peri_master[lchip], 0, sizeof(sys_peri_master_t));

    /* create mutex for chip module */
    ret = sal_mutex_create(&(p_usw_peri_master[lchip]->p_peri_mutex));
    if (ret || (!p_usw_peri_master[lchip]->p_peri_mutex))
    {
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }

    /* create mutex for dynamic switch */
    ret = sal_mutex_create(&(p_usw_peri_master[lchip]->p_switch_mutex));
    if (ret || (!p_usw_peri_master[lchip]->p_switch_mutex))
    {
        ret = CTC_E_NO_MEMORY;
        goto error1;
    }

    /* create mutex for I2C */
    ret = sal_mutex_create(&(p_usw_peri_master[lchip]->p_i2c_mutex));
    if (ret || (!p_usw_peri_master[lchip]->p_i2c_mutex))
    {
        ret = CTC_E_NO_MEMORY;
        goto error2;
    }

    /* create mutex for SMI */
    ret = sal_mutex_create(&(p_usw_peri_master[lchip]->p_smi_mutex));
    if (ret || (!p_usw_peri_master[lchip]->p_smi_mutex))
    {
        ret = CTC_E_NO_MEMORY;
        goto error3;
    }

#ifndef EMULATION_ENV
    /* peri io init */
    if(NULL != MCHIP_PERI(lchip)->peri_init)
    {
        CTC_ERROR_GOTO(MCHIP_PERI(lchip)->peri_init(lchip), ret, error4);
    }
#endif

    return CTC_E_NONE;

#ifndef EMULATION_ENV
error4:
    ctc_sal_mutex_destroy(p_usw_peri_master[lchip]->p_smi_mutex);
#endif
error3:
    ctc_sal_mutex_destroy(p_usw_peri_master[lchip]->p_i2c_mutex);
error2:
    ctc_sal_mutex_destroy(p_usw_peri_master[lchip]->p_switch_mutex);
error1:
    ctc_sal_mutex_destroy(p_usw_peri_master[lchip]->p_peri_mutex);
error0:
    mem_free(p_usw_peri_master[lchip]);

    return ret;
}

int32
sys_usw_peri_deinit(uint8 lchip)
{
    if (NULL == p_usw_peri_master[lchip])
    {
        return CTC_E_NONE;
    }

    SYS_VCHIP_MASTER_DEINIT_GLOBAL(lchip, p_usw_peri_master);

    if (p_usw_peri_master[lchip]->p_peri_mutex)
    {
        sal_mutex_destroy(p_usw_peri_master[lchip]->p_peri_mutex);
    }

    if (p_usw_peri_master[lchip]->p_switch_mutex)
    {
        sal_mutex_destroy(p_usw_peri_master[lchip]->p_switch_mutex);
    }

    if (p_usw_peri_master[lchip]->p_i2c_mutex)
    {
        sal_mutex_destroy(p_usw_peri_master[lchip]->p_i2c_mutex);
    }

    if (p_usw_peri_master[lchip]->p_smi_mutex)
    {
        sal_mutex_destroy(p_usw_peri_master[lchip]->p_smi_mutex);
    }

    mem_free(p_usw_peri_master[lchip]);

    return CTC_E_NONE;
}

int32
sys_usw_mdio_init(uint8 lchip)
{
    if(NULL != MCHIP_PERI(lchip)->peri_mdio_init)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_mdio_init(lchip));
    }
    return CTC_E_NONE;
}

#define __MDIO_INTERFACE__
/**
 @brief set phy to port mapping
*/
int32
sys_usw_peri_get_phy_bitmap(uint8 lchip, uint8 ctl_id, uint32* p_bitmap0, uint32* p_bitmap1)
{
    uint32 cmd = 0;
    uint8 step = 0;
    uint32 tbl_id = 0;
    uint8 index = 0;
    MdioScanCtl0_m scan_ctl;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_bitmap0);
    CTC_PTR_VALID_CHECK(p_bitmap1);

    if (DRV_IS_DUET2(lchip))
    {
        if (0 == ctl_id)
        {
            tbl_id = MdioScanCtl00_t;
        }
        else
        {
            step = MdioScanCtl11_t - MdioScanCtl10_t;
            tbl_id = MdioScanCtl01_t + (ctl_id - 1) * step;
        }
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &scan_ctl);
        GetMdioScanCtl00(A, mdioScanBmp0Lane0_f, &scan_ctl, p_bitmap0);
        GetMdioScanCtl00(A, mdioScanBmp1Lane0_f, &scan_ctl, p_bitmap1);
    }
    else
    {
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            if (0 == ctl_id || 1 == ctl_id)
            {
                tbl_id = MdioScanCtl0_t;
            }
            else
            {
                tbl_id = MdioScanCtl1_t;
            }
            index = ctl_id % SYS_CHIP_CONTROL_NUM;
        }
        else if(DRV_IS_TSINGMA(lchip))
        {
            step = MdioScanCtl1_t - MdioScanCtl0_t;
            tbl_id = MdioScanCtl0_t + ctl_id * step;
            index = 0;
        }
        else
        {
            tbl_id = ((0 == ctl_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE) || (1 == ctl_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE))? MdioScanCtl0_t : MdioScanCtl1_t;
            index = (ctl_id / 2)? 0 : 1;
        }
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &scan_ctl);
        GetMdioScanCtl0(A, mdioScanBmp0Lane0_f, &scan_ctl, p_bitmap0);
        GetMdioScanCtl0(A, mdioScanBmp1Lane0_f, &scan_ctl, p_bitmap1);

    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get Scan Phy bitmap: 0x%x, 0x%x,"
                    "ctl_id: %d\n", *p_bitmap0, *p_bitmap1, ctl_id);

    return CTC_E_NONE;
}

int32
sys_usw_peri_set_phy_bitmap(uint8 lchip, uint8 ctl_id, uint32 bitmap0, uint32 bitmap1)
{
    uint32 cmd = 0;
    uint8 step = 0;
    uint32 tbl_id = 0;
    MdioScanCtl0_m scan_ctl;
    uint8 index = 0;


    SYS_PERI_INIT_CHECK(lchip);

    if (DRV_IS_DUET2(lchip))
    {
        if (0 == ctl_id)
        {
            tbl_id = MdioScanCtl00_t;
        }
        else
        {
            step = MdioScanCtl11_t - MdioScanCtl10_t;
            tbl_id = MdioScanCtl01_t + (ctl_id - 1) * step;
        }
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &scan_ctl);
        SetMdioScanCtl00(V, mdioScanBmp0Lane0_f, &scan_ctl, bitmap0);
        SetMdioScanCtl00(V, mdioScanBmp1Lane0_f, &scan_ctl, bitmap1);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, 0, cmd, &scan_ctl);
    }
    else
    {
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            if (0 == ctl_id || 1 == ctl_id)
            {
                tbl_id = MdioScanCtl0_t;
            }
            else
            {
                tbl_id = MdioScanCtl1_t;
            }
            index = ctl_id % SYS_CHIP_CONTROL_NUM;
        }
        else if(DRV_IS_TSINGMA(lchip))
        {
            step = MdioScanCtl1_t - MdioScanCtl0_t;
            tbl_id = MdioScanCtl0_t + ctl_id * step;
            index = 0;
        }
        else
        {
            tbl_id = ((0 == ctl_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE) || (1 == ctl_id % SYS_PERI_MDIO_CTRL_NUM_PER_CORE))? MdioScanCtl0_t : MdioScanCtl1_t;
            index = (ctl_id / 2)? 0 : 1;
        }
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &scan_ctl);
        SetMdioScanCtl0(V, mdioScanBmp0Lane0_f, &scan_ctl, bitmap0);
        SetMdioScanCtl0(V, mdioScanBmp1Lane0_f, &scan_ctl, bitmap1);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, index, DRV_CMD_PP_EN(cmd), &scan_ctl);
    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set Scan Phy bitmap: 0x%x, 0x%x,"
                    "ctl_id: %d\n", bitmap0, bitmap1, ctl_id);

    return CTC_E_NONE;
}

/* called by MDIO scan init and dynamic switch */
int32
sys_usw_peri_set_phy_scan_cfg(uint8 lchip)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(NULL != MCHIP_PERI(lchip)->peri_set_phy_scan_cfg)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_phy_scan_cfg(lchip));
    }
    return CTC_E_NONE;
}

/**
 @brief smi interface for set auto scan para
*/
int32
sys_usw_peri_set_phy_scan_para(uint8 lchip, ctc_chip_phy_scan_ctrl_t* p_scan_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(NULL != MCHIP_PERI(lchip)->peri_set_phy_scan_para)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_phy_scan_para(lchip, p_scan_para));
    }
    return CTC_E_NONE;
}

/**
 @brief smi interface for sgt auto scan para
*/
int32
sys_usw_peri_get_phy_scan_para(uint8 lchip, ctc_chip_phy_scan_ctrl_t* p_scan_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(NULL != MCHIP_PERI(lchip)->peri_get_phy_scan_para)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_get_phy_scan_para(lchip, p_scan_para));
    }
    return CTC_E_NONE;
}

/**
 @brief smi interface for set auto scan enable or not
*/
int32
sys_usw_peri_set_phy_scan_en(uint8 lchip, bool enable)
{
    uint32 cmd0 = 0, cmd1 = 0;
    uint32 field_value = (TRUE == enable) ? 1 : 0;
    uint8 index = 0;
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set Scan Enable enable:%d\n", ((TRUE == enable) ? 1 : 0));

    if (DRV_IS_DUET2(lchip))
    {
        uint32 cmd2 = 0, cmd3 = 0;
        cmd0 = DRV_IOW(MdioScanCtl00_t, MdioScanCtl00_scanStartLane0_f);
        cmd1 = DRV_IOW(MdioScanCtl01_t, MdioScanCtl01_scanStartLane0_f);
        cmd2 = DRV_IOW(MdioScanCtl10_t, MdioScanCtl10_scanStartLane1_f);
        cmd3 = DRV_IOW(MdioScanCtl11_t, MdioScanCtl11_scanStartLane1_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd0, &field_value));
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd1, &field_value));
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd2, &field_value));
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd3, &field_value));
    }
    else
    {
        for (index = 0; index < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); index++)
        {
            cmd0 = DRV_IOW(MdioScanCtl0_t, MdioScanCtl0_scanStartLane0_f);
            cmd1 = DRV_IOW(MdioScanCtl1_t, MdioScanCtl1_scanStartLane1_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd0, &field_value));
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd1, &field_value));
        }
    }

    return CTC_E_NONE;
}

/**
 @brief smi interface for get auto scan enable or not
*/
int32
sys_usw_peri_get_phy_scan_en(uint8 lchip, bool* enable)
{
    uint32 cmd = 0;
    uint32 field_value = 0;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(enable);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (DRV_IS_DUET2(lchip))
    {
        cmd = DRV_IOR(MdioScanCtl00_t, MdioScanCtl00_scanStartLane0_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    }
    else
    {
        cmd = DRV_IOR(MdioScanCtl0_t, MdioScanCtl0_scanStartLane0_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get Scan Enable enable:%d\n", field_value);
    *enable = field_value;

    return CTC_E_NONE;
}

/**
 @brief mdio interface
*/
int32
sys_usw_peri_mdio_read(uint8 lchip, ctc_chip_mdio_type_t type, ctc_chip_mdio_para_t* p_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_para);

    LCHIP_CHECK(lchip);
    if(NULL != MCHIP_PERI(lchip)->peri_read_phy_reg)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_read_phy_reg(lchip, type, p_para));
    }
    return CTC_E_NONE;
}

/**
 @brief mdio interface
*/
int32
sys_usw_peri_mdio_write(uint8 lchip, ctc_chip_mdio_type_t type, ctc_chip_mdio_para_t* p_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_para);
    LCHIP_CHECK(lchip);
    if(NULL != MCHIP_PERI(lchip)->peri_write_phy_reg)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_write_phy_reg(lchip, type, p_para));
    }
    return CTC_E_NONE;
}

/**
 @brief mdio interface to set mdio clock frequency
*/
int32
sys_usw_peri_set_mdio_clock(uint8 lchip, ctc_chip_mdio_type_t type, uint16 freq)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((type != CTC_CHIP_MDIO_GE) && (type != CTC_CHIP_MDIO_XG))
    {
        return CTC_E_INVALID_PARAM;
    }
    if(NULL != MCHIP_PERI(lchip)->peri_set_mdio_clock)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_mdio_clock(lchip, type, freq));
    }
    return CTC_E_NONE;
}

/**
 @brief mdio interface to get mdio clock frequency
*/
int32
sys_usw_peri_get_mdio_clock(uint8 lchip, ctc_chip_mdio_type_t type, uint16* freq)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(freq);
    if ((type != CTC_CHIP_MDIO_GE) && (type != CTC_CHIP_MDIO_XG))
    {
        return CTC_E_INVALID_PARAM;
    }
    if(NULL != MCHIP_PERI(lchip)->peri_get_mdio_clock)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_get_mdio_clock(lchip, type, freq));
    }
    return CTC_E_NONE;
}


/**
 @brief mdio interface to set mdc voltage
*/
STATIC int32
_sys_usw_peri_set_mdc_voltage_mode(uint8 lchip, uint32 mode)
{
    ds_t mdio_ctl;
    uint8 ctl_id = 0;
    uint32 cmd = 0;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (DRV_IS_DUET2(lchip) || DRV_IS_AT(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    CTC_MAX_VALUE_CHECK(mode, SYS_MDC_MAX_VOLTAGE_MODE);
    sal_memset(&mdio_ctl, 0, sizeof(ds_t));
    /*
    TM.MX: MdioAPadCtl.pmsMdioA
    TM: MdioPadCtl.mdcA0Msc and MdioPadCtl.mdioA0Msc
    */
    if (DRV_IS_TSINGMA(lchip))
    {
        cmd = DRV_IOR(MdioPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        for (ctl_id = 0; ctl_id < MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) * SYS_CHIP_BUS_NUM_PER_CTL; ctl_id++)
        {
            SetMdioPadCtl(V, mdcA0Msc_f + ctl_id * SYS_CHIP_BUS_NUM_PER_CTL, &mdio_ctl, mode);
            SetMdioPadCtl(V, mdioA0Msc_f + ctl_id * SYS_CHIP_BUS_NUM_PER_CTL, &mdio_ctl, mode);
        }
        cmd = DRV_IOW(MdioPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
    }
    else
    {
        uint32 mdio_tbl_id[] = {MdioAPadCtl_t, MdioCPadCtl_t, MdioBPadCtl_t, MdioDPadCtl_t};
        for (ctl_id = 0; ctl_id < MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM); ctl_id++)
        {
            cmd = DRV_IOR(mdio_tbl_id[ctl_id], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
            SetMdioAPadCtl(V, pmsMdioA_f, &mdio_ctl, mode);
            cmd = DRV_IOW(mdio_tbl_id[ctl_id], DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        }
    }
    return CTC_E_NONE;
}

/**
 @brief mdio interface to get mdio clock frequency
*/
STATIC int32
_sys_usw_peri_get_mdc_voltage_mode(uint8 lchip, uint32* mode)
{
    uint32 cmd = 0;
    ds_t mdio_ctl;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_PTR_VALID_CHECK(mode);
    if (DRV_IS_DUET2(lchip) || DRV_IS_AT(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    sal_memset(&mdio_ctl, 0, sizeof(ds_t));
    cmd = DRV_IOR((DRV_IS_TSINGMA(lchip)? MdioPadCtl_t: MdioAPadCtl_t), DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
    if (DRV_IS_TSINGMA(lchip))
    {
        *mode = GetMdioPadCtl(V, mdcA0Msc_f, &mdio_ctl);
    }
    else
    {
        *mode = GetMdioAPadCtl(V, pmsMdioA_f, &mdio_ctl);
    }

    return CTC_E_NONE;
}

/**
 @brief mdio interface to set mdio clock frequency
*/
int32
_sys_usw_peri_set_mdio_drv_cap(uint8 lchip, uint8 bus_id, uint32 val)
{
    ds_t mdio_ctl;
    uint8 ctl_id = 0;
    uint8 mdio_bus = 0;
    uint32 cmd = 0;

    SYS_PERI_INIT_CHECK(lchip);
    if (DRV_FROM_AT(lchip))
    {
        CTC_MAX_VALUE_CHECK(bus_id, (MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));
    }
    else
    {
        CTC_MAX_VALUE_CHECK(bus_id, (SYS_CHIP_BUS_NUM_PER_CTL * MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set mdio drvive capaility: bus_id %u value %u\n", bus_id, val);

    if ((SDK_WORK_PLATFORM != 0) || DRV_IS_DUET2(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }

    /* 
    TM.MX: MdioAPadCtl.pdrvMdcA0
    TM: MdioPadCtl.mdcA0Drv and MdioPadCtl.mdioA0Drv
    */
    sal_memset(&mdio_ctl, 0, sizeof(ds_t));
    ctl_id = bus_id / SYS_CHIP_BUS_NUM_PER_CTL;
    mdio_bus = bus_id % SYS_CHIP_BUS_NUM_PER_CTL;
    if (DRV_IS_TSINGMA(lchip))
    {
        uint32 field_id = 0;
        CTC_MAX_VALUE_CHECK(val, SYS_TM_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(MdioPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        field_id = MdioPadCtl_mdcA0Drv_f + mdio_bus*(MdioPadCtl_mdcA1Drv_f-MdioPadCtl_mdcA0Drv_f) +ctl_id *(MdioPadCtl_mdcB0Drv_f-MdioPadCtl_mdcA0Drv_f);
        DRV_SET_FIELD_V(lchip, MdioPadCtl_t, field_id, &mdio_ctl, val);
        field_id = MdioPadCtl_mdioA0Drv_f + mdio_bus*(MdioPadCtl_mdioA1Drv_f-MdioPadCtl_mdioA0Drv_f) +ctl_id *(MdioPadCtl_mdioB0Drv_f-MdioPadCtl_mdioA0Drv_f);
        DRV_SET_FIELD_V(lchip, MdioPadCtl_t, field_id, &mdio_ctl, val);
        cmd = DRV_IOW(MdioPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
    }
    else if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        uint32 mdio_tbl_id[] = {MdioAPadCtl_t, MdioCPadCtl_t, MdioBPadCtl_t, MdioDPadCtl_t};
        CTC_MAX_VALUE_CHECK(val, SYS_USW_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(mdio_tbl_id[ctl_id] , DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        SetMdioAPadCtl(V, pdrvMdcA0_f+mdio_bus*(MdioAPadCtl_pdrvMdcA1_f-MdioAPadCtl_pdrvMdcA0_f), &mdio_ctl, val);
        SetMdioAPadCtl(V, pdrvMdioA0_f+mdio_bus*(MdioAPadCtl_pdrvMdioA1_f-MdioAPadCtl_pdrvMdioA0_f), &mdio_ctl, val);
        cmd = DRV_IOW(mdio_tbl_id[ctl_id], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
    }
    else if(DRV_FROM_AT(lchip))
    {
        uint32 mdio_tbl_id[] = {MdioA0PadCfg_t, MdioA1PadCfg_t, MdioA2PadCfg_t, MdioA3PadCfg_t, MdioB0PadCfg_t, MdioB1PadCfg_t, MdioB2PadCfg_t, MdioB3PadCfg_t};
        CTC_MAX_VALUE_CHECK(val, SYS_AT_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(mdio_tbl_id[bus_id] , DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        SetMdioA0PadCfg(V, cfgDcsMdcA0_f, &mdio_ctl, val);
        SetMdioA0PadCfg(V, cfgDcsMdioA0_f, &mdio_ctl, val);
        cmd = DRV_IOW(mdio_tbl_id[bus_id], DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mdio_ctl));
    }

    return CTC_E_NONE;
}

/**
 @brief mdio interface to get mdio clock frequency
*/
int32
_sys_usw_peri_get_mdio_drv_cap(uint8 lchip, uint8 bus_id, uint32* p_val)
{
    ds_t mdio_ctl;
    uint8 ctl_id = 0;
    uint8 mdio_bus = 0;
    uint32 cmd = 0;

    SYS_PERI_INIT_CHECK(lchip);
    if (DRV_FROM_AT(lchip))
    {
        CTC_MAX_VALUE_CHECK(bus_id, (MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));
    }
    else
    {
        CTC_MAX_VALUE_CHECK(bus_id, (SYS_CHIP_BUS_NUM_PER_CTL * MCHIP_CAP(SYS_CAP_MDIO_CTL_NUM) - 1));
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get mdio drvive capaility: bus_id %u\n", bus_id);

    if ((SDK_WORK_PLATFORM != 0) || DRV_IS_DUET2(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }

    /* 
    TM.MX: MdioAPadCtl.pdrvMdcA0
    TM: MdioPadCtl.mdcA0Drv and MdioPadCtl.mdioA0Drv
    */
    sal_memset(&mdio_ctl, 0, sizeof(ds_t));
    ctl_id = bus_id / SYS_CHIP_BUS_NUM_PER_CTL;
    mdio_bus = bus_id % SYS_CHIP_BUS_NUM_PER_CTL;
    if (DRV_IS_TSINGMA(lchip))
    {
        uint32 field_id = 0;
        cmd = DRV_IOR(MdioPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        field_id = MdioPadCtl_mdcA0Drv_f + mdio_bus*(MdioPadCtl_mdcA1Drv_f-MdioPadCtl_mdcA0Drv_f) +ctl_id *(MdioPadCtl_mdcB0Drv_f-MdioPadCtl_mdcA0Drv_f);
        *p_val = DRV_GET_FIELD_V(lchip, MdioPadCtl_t, field_id, &mdio_ctl);
    }
    else if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        uint32 mdio_tbl_id[] = {MdioAPadCtl_t, MdioCPadCtl_t, MdioBPadCtl_t, MdioDPadCtl_t};
        cmd = DRV_IOR(mdio_tbl_id[ctl_id] , DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &mdio_ctl));
        *p_val = GetMdioAPadCtl(V, pdrvMdcA0_f+mdio_bus*(MdioAPadCtl_pdrvMdcA1_f-MdioAPadCtl_pdrvMdcA0_f), &mdio_ctl);
    }
    else if (DRV_FROM_AT(lchip))
    {
        uint32 mdio_tbl_id[] = {MdioA0PadCfg_t, MdioA1PadCfg_t, MdioA2PadCfg_t, MdioA3PadCfg_t, MdioB0PadCfg_t, MdioB1PadCfg_t, MdioB2PadCfg_t, MdioB3PadCfg_t};
        cmd = DRV_IOR(mdio_tbl_id[bus_id] , DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &mdio_ctl));
        *p_val = GetMdioA0PadCfg(V, cfgDcsMdcA0_f, &mdio_ctl);
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get mdio drvive capaility: value %u\n", *p_val);

    return CTC_E_NONE;
}

#define __I2C_MASTER_INTERFACE__

STATIC int32
_sys_usw_peri_i2c_set_switch(uint8 lchip, uint8 ctl_id, uint8 i2c_switch_id)
{
    uint32 cmd = 0;
    uint32 field_value = 0;

    field_value = (SYS_CHIP_INVALID_SWITCH_ID != i2c_switch_id)? 1 : 0;
    cmd = DRV_IOW(I2CMasterCfg0_t + ctl_id, I2CMasterCfg0_switchEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));

    if (i2c_switch_id)
    {
        field_value = 0xe ;/* pca9548a device fixed address */
        cmd = DRV_IOW(I2CMasterCfg0_t + ctl_id, I2CMasterCfg0_switchAddr_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_set_i2c_byte_access(uint8 lchip, uint8 ctl_id, bool enable)
{

    uint32 cmd = 0;
    uint32 field_value = 0;
    uint32 tbl_id = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set byte access enable:%d\n", (enable ? 1 : 0));

    tbl_id = ctl_id ? I2CMasterCfg1_t : I2CMasterCfg0_t ;

    field_value = enable ? 1 : 0;
    cmd = DRV_IOW(tbl_id, I2CMasterCfg0_currentByteAcc_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0,  DRV_CMD_PP_EN(cmd), &field_value));

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_set_bitmap_ctl(uint8 lchip, ctc_chip_i2c_read_t* p_i2c_para)
{
    sys_chip_i2c_slave_bitmap_t slave_bitmap = {0};
    I2CMasterBmpCfg0_m bitmap_ctl;
    uint32 cmd = 0;
    int32 ret = 0;

    sal_memset(&bitmap_ctl, 0, sizeof(I2CMasterBmpCfg0_m));

    if (SYS_CHIP_I2C_32BIT_DEV_ID > p_i2c_para->slave_dev_id)
    {
        slave_bitmap.slave_bitmap1 = (0x1 << p_i2c_para->slave_dev_id);
    }
    else if(SYS_CHIP_I2C_MAX_BITAMP > p_i2c_para->slave_dev_id)
    {
        slave_bitmap.slave_bitmap2 = (0x1 << (p_i2c_para->slave_dev_id - SYS_CHIP_I2C_32BIT_DEV_ID));
    }
    else
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_bitmap_ctl: slave_dev_id(%d) out of bound!\n", p_i2c_para->slave_dev_id);
        return CTC_E_INVALID_PARAM;
    }

    SetI2CMasterBmpCfg(p_i2c_para->ctl_id, &bitmap_ctl, &slave_bitmap);
    cmd = DRV_IOW(I2CMasterBmpCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &bitmap_ctl);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_bitmap_ctl: write table fail! ctl_id %d, slave_bitmap1 %d, slave_bitmap2 %d\n",
                         p_i2c_para->ctl_id, slave_bitmap.slave_bitmap1, slave_bitmap.slave_bitmap2);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_set_master_read(uint8 lchip, ctc_chip_i2c_read_t* p_i2c_para)
{
    int32 ret = 0;
    uint32 cmd = 0;
    I2CMasterReadCfg0_m master_rd;
    I2CMasterReadCtl0_m read_ctl;
    I2CMasterReadStatus0_m read_status;

    sal_memset(&master_rd, 0, sizeof(I2CMasterReadCfg0_m));
    sal_memset(&read_ctl, 0, sizeof(I2CMasterReadCtl0_m));

    /*Before trigger read, clear old status*/
    cmd = DRV_IOR(I2CMasterReadStatus0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &read_status);

    SetI2CMasterReadCfg(p_i2c_para->ctl_id, slaveAddr_f, &master_rd, p_i2c_para->dev_addr);
    SetI2CMasterReadCfg(p_i2c_para->ctl_id, offset_f, &master_rd, p_i2c_para->offset);
    SetI2CMasterReadCfg(p_i2c_para->ctl_id, length_f, &master_rd, p_i2c_para->length);
    cmd = DRV_IOW(I2CMasterReadCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &master_rd);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_master_read: I2CMasterReadCfg error! %d\n", ret);
        return CTC_E_INVALID_CONFIG;
    }

    SetI2CMasterReadCtl(p_i2c_para->ctl_id, pollingSel_f, &read_ctl, 0);
    SetI2CMasterReadCtl(p_i2c_para->ctl_id, readEn_f, &read_ctl, 1);
    cmd = DRV_IOW(I2CMasterReadCtl0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &read_ctl);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_master_read: I2CMasterReadCtl error! %d\n", ret);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_check_master_status(uint8 lchip, ctc_chip_i2c_read_t* p_i2c_para)
{
    uint32 cmd = 0;
    int32 ret = 0;
    uint32 timeout = 0;
    uint32 field_value = 0;
    I2CMasterStatus0_m master_status;

    sal_memset(&master_status, 0, sizeof(I2CMasterStatus0_m));
    timeout = 4 * p_i2c_para->length;

    cmd = DRV_IOR(I2CMasterStatus0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);

    do
    {
        sal_task_sleep(1);
        ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &master_status);
        if (ret < 0)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_master_status: I2CMasterStatus error! %d\n", ret);
            return CTC_E_INVALID_CONFIG;
        }
        GetI2CMasterStatus(p_i2c_para->ctl_id, triggerReadValid_f,
                        &master_status, field_value);
    }while ((field_value == 0) && (timeout--));

    if (0 == field_value)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "i2c master read cmd not done! line = %d\n",  __LINE__);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_read_data(uint8 lchip, ctc_chip_i2c_read_t* p_i2c_para)
{
    uint8 index = 0;
    uint32 cmd = 0;
    int32 ret = 0;
    uint32 field_value = 0;
    uint32 tbl_id = DRV_FROM_AT(lchip) ? I2CMasterDataMem_t : I2CMasterDataMem0_t + p_i2c_para->ctl_id;
    uint16 idx_offset = DRV_FROM_AT(lchip) ? p_i2c_para->ctl_id * SYS_CHIP_I2C_READ_MAX_LENGTH : 0;
    I2CMasterDataMem0_m data_buf;

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);

    for (index = 0; index < p_i2c_para->length; index++)
    {
        ret = DRV_IOCTL(lchip, index + idx_offset, DRV_CMD_PP_EN(cmd), &data_buf);
        if (ret < 0)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_read_data: I2CMasterDataMem error! %d %d\n", ret, p_i2c_para->ctl_id);
            return CTC_E_INVALID_CONFIG;
        }

        if (DRV_FROM_AT(lchip))
        {
            p_i2c_para->p_buf[index] = GetI2CMasterDataMem(V, data_f, &data_buf);
        }
        else
        {
            p_i2c_para->p_buf[index] = GetI2CMasterDataMem0(V, data_f, &data_buf);
        }
    }

    /* clear read cmd */
    field_value = 0;
    cmd = DRV_IOW(I2CMasterReadCtl0_t + p_i2c_para->ctl_id, I2CMasterReadCtl0_readEn_f);
    ret = DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_read_data: I2CMasterReadCtl error! %d %d\n", ret, p_i2c_para->ctl_id);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_check_data(uint8 lchip, ctc_chip_i2c_read_t* p_i2c_para)

{
    uint32 cmd = 0;
    int32 ret = 0;
    uint32 arr_read_status[2] = {0};
    I2CMasterReadStatus0_m read_status;

    sal_memset(&read_status, 0, sizeof(I2CMasterReadStatus0_m));

    /*check read status */
    cmd = DRV_IOR(I2CMasterReadStatus0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &read_status);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_data: I2CMasterReadStatus error! %d %d\n", ret, p_i2c_para->ctl_id);
        return CTC_E_INVALID_CONFIG;
    }
    GetI2CMasterReadStatus(p_i2c_para->ctl_id, &read_status, arr_read_status);

    if ((0 != arr_read_status[0]) || (0 != arr_read_status[1]))
    {

        if (p_i2c_para->p_buf[0] == 0xff)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_data: p_buf[0] == 0xff\n");
            return CTC_E_INVALID_CONFIG;
        }
        else if (p_i2c_para->p_buf[0] == 0)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_data: p_buf[0] == 0\n");
            return CTC_E_INVALID_CONFIG;
        }
        else
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_data: p_buf[0] %d\n", p_i2c_para->p_buf[0]);
            return CTC_E_INVALID_CONFIG;
        }
    }

    return CTC_E_NONE;
}

/**
 @brief i2c master for read sfp
*/
int32
sys_usw_peri_i2c_read(uint8 lchip, ctc_chip_i2c_read_t* p_i2c_para)
{
    int32 ret = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    uint32 field_value1 = 0;
    I2CMasterReadCtl0_m read_ctl;

    CTC_PTR_VALID_CHECK(p_i2c_para);
    CTC_PTR_VALID_CHECK(p_i2c_para->p_buf);
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "read sfp, bitmap:0x%x addr:0x%x  offset:0x%x length:0x%x \n",
                     p_i2c_para->slave_bitmap, p_i2c_para->dev_addr, p_i2c_para->offset, p_i2c_para->length);

    if(0x3ff < p_i2c_para->dev_addr)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_usw_peri_i2c_read: out of bound!\n");
        return CTC_E_INTR_INVALID_PARAM;
    }

    if ((p_i2c_para->buf_length < p_i2c_para->length) || (0 == p_i2c_para->length)
        || (p_i2c_para->ctl_id > MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1))
    {
        return CTC_E_INVALID_PARAM;
    }

    sal_memset(&read_ctl, 0, sizeof(I2CMasterReadCtl0_m));
    cmd = DRV_IOR(I2CMasterReadCtl0_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &read_ctl);
    DRV_IOR_FIELD(lchip, I2CMasterReadCtl0_t, I2CMasterReadCtl0_readEn_f, &field_value, &read_ctl);
    sal_memset(&read_ctl, 0, sizeof(I2CMasterReadCtl0_m));
    cmd = DRV_IOR(I2CMasterReadCtl1_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, 0, cmd, &read_ctl);
    DRV_IOR_FIELD(lchip, I2CMasterReadCtl1_t, I2CMasterReadCtl1_readEn_f, &field_value1, &read_ctl);
    if(field_value || field_value1)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_usw_peri_i2c_read: i2c-scan is running!\n");
        return CTC_E_INVALID_PARAM;
    }

    SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, p_i2c_para->ctl_id);
    p_i2c_para->ctl_id = DRV_FROM_AT(lchip) ? p_i2c_para->ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE : p_i2c_para->ctl_id;
    SYS_PERI_I2C_LOCK(lchip);

    if (p_i2c_para->access_switch)
    {
        p_i2c_para->i2c_switch_id = 0;
        p_i2c_para->length = 1;
        CTC_ERROR_GOTO(_sys_usw_peri_set_i2c_byte_access(lchip, p_i2c_para->ctl_id, TRUE), ret, EXIT);
    }

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_set_switch(lchip, p_i2c_para->ctl_id, p_i2c_para->i2c_switch_id),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_set_bitmap_ctl(lchip, p_i2c_para),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_set_master_read(lchip, p_i2c_para),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_check_master_status(lchip, p_i2c_para),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_read_data(lchip, p_i2c_para),
        ret, error_0);

    /*check read status */
    CTC_ERROR_GOTO( _sys_usw_peri_i2c_check_data(lchip, p_i2c_para),
        ret, error_0);

error_0:
    if (p_i2c_para->access_switch)
    {
        CTC_ERROR_GOTO(_sys_usw_peri_set_i2c_byte_access(lchip, p_i2c_para->ctl_id, FALSE), ret, EXIT);
    }

    /* clear read cmd */
    field_value = 0;
    cmd = DRV_IOW(I2CMasterReadCtl0_t + p_i2c_para->ctl_id, I2CMasterReadCtl0_readEn_f);
    DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value);
EXIT:
    SYS_PERI_I2C_UNLOCK(lchip);
    return ret;
}

STATIC int32
_sys_usw_peri_i2c_set_write_bitmap_ctl(uint8 lchip, ctc_chip_i2c_write_t* p_i2c_para)
{
    sys_chip_i2c_slave_bitmap_t slave_bitmap = {0};
    I2CMasterBmpCfg0_m bitmap_ctl;
    uint32 cmd = 0;
    int32 ret = 0;

    sal_memset(&bitmap_ctl, 0, sizeof(I2CMasterBmpCfg0_m));

    if (SYS_CHIP_I2C_32BIT_DEV_ID > p_i2c_para->slave_id)
    {
        slave_bitmap.slave_bitmap1 = (0x1 << p_i2c_para->slave_id);
    }
    else if(SYS_CHIP_I2C_MAX_BITAMP > p_i2c_para->slave_id)
    {
        slave_bitmap.slave_bitmap2 = (0x1 << (p_i2c_para->slave_id - SYS_CHIP_I2C_32BIT_DEV_ID));
    }
    else
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_bitmap_ctl: slave_id(%d) out of bound!\n", p_i2c_para->slave_id);
        return CTC_E_INVALID_PARAM;
    }

    SetI2CMasterBmpCfg(p_i2c_para->ctl_id, &bitmap_ctl, &slave_bitmap);

    cmd = DRV_IOW(I2CMasterBmpCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &bitmap_ctl);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_write_bitmap_ctl: I2CMasterBmpCfg error! %d %d\n",
                         p_i2c_para->ctl_id, ret);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_set_write_master(uint8 lchip, ctc_chip_i2c_write_t* p_i2c_para)
{
    int32 ret = 0;
    uint32 cmd = 0;
    uint32 field_value = 0;
    I2CMasterReadCfg0_m master_rd;
    I2CMasterStatus0_m master_status;

    sal_memset(&master_rd, 0, sizeof(I2CMasterReadCfg0_m));
    sal_memset(&master_status, 0, sizeof(I2CMasterStatus0_m));

    /* check status */
    if (p_i2c_para->ctl_id)
    {
        cmd = DRV_IOR(I2CMasterReadCtl1_t, I2CMasterReadCtl1_readEn_f);
    }
    else
    {
        cmd = DRV_IOR(I2CMasterReadCtl0_t, I2CMasterReadCtl0_readEn_f);
    }

    ret = DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_write_master: I2CMasterReadCtl error! %d %d\n",
                         p_i2c_para->ctl_id, ret);
        return CTC_E_INVALID_CONFIG;
    }

    if (field_value != 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_write_master: field_value %d \n", field_value);
        return CTC_E_INVALID_CONFIG;
    }

#if 0
    /*
        hardware is not sure to set pollingDone_f 1
    */
    cmd = DRV_IOR(I2CMasterStatus0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(p_i2c_para->lchip, 0, cmd, &master_status);
    if (ret < 0)
    {
        return DRV_E_I2C_MASTER_CMD_ERROR;
    }

    GetI2CMasterStatus(p_i2c_para->ctl_id, pollingDone_f, &master_status, polling_done);

    if (polling_done != 1)
    {
        /* chip init status polling_done is set */
        DRV_DBG_INFO("i2c master write check polling fail! line = %d\n",  __LINE__);
        return DRV_E_I2C_MASTER_POLLING_NOT_DONE;
    }
#endif

    SetI2CMasterReadCfg(p_i2c_para->ctl_id, slaveAddr_f, &master_rd, p_i2c_para->dev_addr);
    SetI2CMasterReadCfg(p_i2c_para->ctl_id, offset_f, &master_rd, p_i2c_para->offset);
    cmd = DRV_IOW(I2CMasterReadCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &master_rd);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_set_write_master: I2CMasterReadCfg error! %d %d\n", p_i2c_para->ctl_id, ret);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_write_data(uint8 lchip, ctc_chip_i2c_write_t* p_i2c_para)
{
    uint32 cmd = 0;
    int32 ret = 0;
    I2CMasterWrCfg0_m master_wr;

    sal_memset(&master_wr, 0, sizeof(I2CMasterWrCfg0_m));

    SetI2CMasterWrCfg(p_i2c_para->ctl_id, wrData_f, &master_wr, p_i2c_para->data);
    SetI2CMasterWrCfg(p_i2c_para->ctl_id, wrEn_f, &master_wr, 1);
    cmd = DRV_IOW(I2CMasterWrCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &master_wr);
    if (ret < 0)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_write_data: I2CMasterWrCfg error! %d %d\n", p_i2c_para->ctl_id, ret);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_i2c_check_write_finish(uint8 lchip, ctc_chip_i2c_write_t* p_i2c_para)
{
    uint32 cmd_cfg = 0;
    uint32 cmd_dbg = 0;
    int32 ret = 0;
    uint32 timeout = 4;
    I2CMasterWrCfg0_m master_wr;
    I2CMasterDebugState0_m master_dbg;
    uint8 i2c_wr_en = 0;
    uint32 i2c_status = 0;

    sal_memset(&master_wr, 0, sizeof(I2CMasterWrCfg0_m));
    sal_memset(&master_dbg, 0, sizeof(I2CMasterDebugState0_m));

    /* wait write op done */
    cmd_cfg = DRV_IOR(I2CMasterWrCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
    cmd_dbg = DRV_IOR(I2CMasterDebugState0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);

    do
    {
        sal_task_sleep(1);
        ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd_cfg), &master_wr);
        if (ret < 0)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_write_finish: I2CMasterWrCfg error! %d %d\n", p_i2c_para->ctl_id, ret);
            return CTC_E_INVALID_CONFIG;
        }
        GetI2CMasterWrCfg(p_i2c_para->ctl_id, wrEn_f, &master_wr, i2c_wr_en );

        ret = DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd_dbg), &master_dbg);
        if (ret < 0)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_i2c_check_write_finish: I2CMasterDebugState error! %d %d\n", p_i2c_para->ctl_id, ret);
            return CTC_E_INVALID_CONFIG;
        }
        GetI2CMasterDebugState(p_i2c_para->ctl_id, i2cAccState_f, &master_dbg, i2c_status);
    }while (((0 != i2c_wr_en) || (0 != i2c_status)) && (--timeout));

    if (((0 != i2c_wr_en) || (0 != i2c_status)))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "i2c master write cmd not done! line = %d\n \
                    wrEn:%u, i2cAccState:%u \n",  __LINE__, i2c_wr_en, i2c_status);
        return CTC_E_INVALID_CONFIG;
    }
    return CTC_E_NONE;
}

/**
 @brief i2c master for write sfp
*/
int32
sys_usw_peri_i2c_write(uint8 lchip, ctc_chip_i2c_write_t* p_i2c_para)
{
    int32 ret = 0;

    CTC_PTR_VALID_CHECK(p_i2c_para);
    SYS_PERI_INIT_CHECK(lchip);
    CTC_MAX_VALUE_CHECK(p_i2c_para->ctl_id , MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "write sfp, slave_id:0x%x addr:0x%x  offset:0x%x data:0x%x \n",
                     p_i2c_para->slave_id, p_i2c_para->dev_addr, p_i2c_para->offset, p_i2c_para->data);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "chip-id:%u \n",
                     p_i2c_para->lchip);

    CTC_PTR_VALID_CHECK(p_i2c_para);

    SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, p_i2c_para->ctl_id);
    p_i2c_para->ctl_id = DRV_FROM_AT(lchip) ? p_i2c_para->ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE : p_i2c_para->ctl_id;
    SYS_PERI_I2C_LOCK(lchip);
    if (p_i2c_para->access_switch)
    {
        p_i2c_para->i2c_switch_id = 0;
        CTC_ERROR_GOTO(_sys_usw_peri_set_i2c_byte_access(lchip, p_i2c_para->ctl_id, TRUE), ret, EXIT);
    }

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_set_switch(lchip, p_i2c_para->ctl_id, p_i2c_para->i2c_switch_id),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_set_write_bitmap_ctl(lchip, p_i2c_para),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_set_write_master(lchip, p_i2c_para),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_write_data(lchip, p_i2c_para),
        ret, error_0);

    CTC_ERROR_GOTO(_sys_usw_peri_i2c_check_write_finish(lchip, p_i2c_para),
        ret, error_0);

error_0:
    if (p_i2c_para->access_switch)
    {
        CTC_ERROR_GOTO(_sys_usw_peri_set_i2c_byte_access(lchip, p_i2c_para->ctl_id, FALSE), ret, EXIT);
    }
EXIT:
    SYS_PERI_I2C_UNLOCK(lchip);
    return CTC_E_NONE;
}


/**
 @brief set i2c polling read para
*/
STATIC int32
_sys_usw_peri_set_i2c_scan_para(uint8 lchip, ctc_chip_i2c_scan_t* p_i2c_para)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    I2CMasterReadCfg0_m master_rd;
    I2CMasterReadCtl0_m read_ctl;
    I2CMasterBmpCfg0_m bitmap_ctl;
    I2CMasterPollingCfg0_m polling_cfg;  /*check*/
    uint8 slave_num = 0;
    uint8 index = 0;

    sal_memset(&master_rd, 0, sizeof(I2CMasterReadCfg0_m));
    sal_memset(&read_ctl, 0, sizeof(I2CMasterReadCtl0_m));
    sal_memset(&bitmap_ctl, 0, sizeof(I2CMasterBmpCfg0_m));
    sal_memset(&polling_cfg, 0, sizeof(I2CMasterPollingCfg0_m));

    CTC_ERROR_RETURN(_sys_usw_peri_i2c_set_switch(lchip, p_i2c_para->ctl_id, p_i2c_para->i2c_switch_id));

    if (SYS_CHIP_FLAG_ISSET(p_i2c_para->op_flag, SYS_CHIP_SFP_BITMAP_OP)
        || SYS_CHIP_FLAG_ISZERO(p_i2c_para->op_flag))
    {
        SetI2CMasterBmpCfg(p_i2c_para->ctl_id, &bitmap_ctl, p_i2c_para->slave_bitmap);
        cmd = DRV_IOW(I2CMasterBmpCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &bitmap_ctl));
        for (index = 0; index < 32; index++)
        {
            if (CTC_IS_BIT_SET(p_i2c_para->slave_bitmap[p_i2c_para->ctl_id], index))
            {
                slave_num++;
            }
        }
    }

    if (SYS_CHIP_FLAG_ISSET(p_i2c_para->op_flag, SYS_CHIP_SFP_SCAN_REG_OP)
        || SYS_CHIP_FLAG_ISZERO(p_i2c_para->op_flag))
    {
        if ((slave_num*p_i2c_para->length) > SYS_CHIP_I2C_READ_MAX_LENGTH)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_set_i2c_scan_para: length over 384, salve_num %d length %d\n",
                     slave_num, p_i2c_para->length);

            return CTC_E_INVALID_PARAM;
        }

        SetI2CMasterReadCfg(p_i2c_para->ctl_id, slaveAddr_f,
                        &master_rd, p_i2c_para->dev_addr);
        SetI2CMasterReadCfg(p_i2c_para->ctl_id, length_f,
                        &master_rd, p_i2c_para->length);
        SetI2CMasterReadCfg(p_i2c_para->ctl_id, offset_f,
                        &master_rd, p_i2c_para->offset);
        cmd = DRV_IOW(I2CMasterReadCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &master_rd));
    }

    if (SYS_CHIP_FLAG_ISSET(p_i2c_para->op_flag, SYS_CHIP_SFP_INTERVAL_OP)
        || SYS_CHIP_FLAG_ISZERO(p_i2c_para->op_flag))
    {
        SetI2CMasterPollingCfg(p_i2c_para->ctl_id, pollingInterval_f,
                            &polling_cfg, p_i2c_para->interval);
        cmd = DRV_IOW(I2CMasterPollingCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &polling_cfg));
    }

    field_value = 1;
    if (p_i2c_para->ctl_id)
    {
        cmd = DRV_IOW(I2CMasterReadCtl1_t, I2CMasterReadCtl1_pollingSel_f);
    }
    else
    {
        cmd = DRV_IOW(I2CMasterReadCtl0_t, I2CMasterReadCtl0_pollingSel_f);
    }
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    return CTC_E_NONE;
}

/**
 @brief get i2c polling read para
*/
STATIC int32
_sys_usw_peri_get_i2c_scan_para(uint8 lchip, ctc_chip_i2c_scan_t* p_i2c_para)
{
    uint32 cmd = 0;
    uint32 field_value = 0;
    I2CMasterReadCfg0_m master_rd;
    I2CMasterPollingCfg0_m polling_cfg;  /*check*/

    sal_memset(&master_rd, 0, sizeof(I2CMasterReadCfg0_m));
    sal_memset(&polling_cfg, 0, sizeof(I2CMasterPollingCfg0_m));

    cmd = DRV_IOR(I2CMasterCfg0_t + p_i2c_para->ctl_id, I2CMasterCfg0_switchEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));
    p_i2c_para->i2c_switch_id = field_value;

    if (SYS_CHIP_FLAG_ISSET(p_i2c_para->op_flag, SYS_CHIP_SFP_BITMAP_OP)
        || SYS_CHIP_FLAG_ISZERO(p_i2c_para->op_flag))
    {
        cmd = DRV_IOR(I2CMasterBmpCfg0_t + p_i2c_para->ctl_id, I2CMasterBmpCfg0_slaveBitmap_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, p_i2c_para->slave_bitmap));
    }

    if (SYS_CHIP_FLAG_ISSET(p_i2c_para->op_flag, SYS_CHIP_SFP_SCAN_REG_OP)
        || SYS_CHIP_FLAG_ISZERO(p_i2c_para->op_flag))
    {
        cmd = DRV_IOR(I2CMasterReadCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &master_rd));
        DRV_IOR_FIELD(lchip, I2CMasterReadCfg0_t + p_i2c_para->ctl_id, I2CMasterReadCfg0_slaveAddr_f,
                        &field_value, &master_rd);
        p_i2c_para->dev_addr = field_value;
        DRV_IOR_FIELD(lchip, I2CMasterReadCfg0_t + p_i2c_para->ctl_id, I2CMasterReadCfg0_length_f,
                        &field_value, &master_rd);
        p_i2c_para->length = field_value;
        DRV_IOR_FIELD(lchip, I2CMasterReadCfg0_t + p_i2c_para->ctl_id, I2CMasterReadCfg0_offset_f,
                        &field_value, &master_rd);
        p_i2c_para->offset = field_value;
    }

    if (SYS_CHIP_FLAG_ISSET(p_i2c_para->op_flag, SYS_CHIP_SFP_INTERVAL_OP)
        || SYS_CHIP_FLAG_ISZERO(p_i2c_para->op_flag))
    {
        cmd = DRV_IOR(I2CMasterPollingCfg0_t + p_i2c_para->ctl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &polling_cfg));
        DRV_IOR_FIELD(lchip, I2CMasterPollingCfg0_t + p_i2c_para->ctl_id, I2CMasterPollingCfg0_pollingInterval_f,
                        &field_value, &polling_cfg);
        p_i2c_para->interval = field_value;
    }

    return CTC_E_NONE;
}

/**
 @brief i2c master for polling read
*/
int32
sys_usw_peri_set_i2c_scan_para(uint8 lchip, ctc_chip_i2c_scan_t* p_i2c_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_i2c_para);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "scan sfp, op_flag:0x%x, bitmap:0x%x addr:0x%x  offset:0x%x length:0x%x intreval:0x%x\n",
                     p_i2c_para->op_flag, p_i2c_para->slave_bitmap[0], p_i2c_para->dev_addr, p_i2c_para->offset, p_i2c_para->length, p_i2c_para->interval);
    if((MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1 < p_i2c_para->ctl_id) ||
       (0x3ff < p_i2c_para->dev_addr) ||
       (0xffff < p_i2c_para->slave_bitmap[1]))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "_sys_usw_peri_set_i2c_scan_para: out of bound! %d %d %d %d\n",
                         p_i2c_para->ctl_id, p_i2c_para->dev_addr, p_i2c_para->length, p_i2c_para->offset);
        return CTC_E_INVALID_PARAM;
    }
    SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, p_i2c_para->ctl_id);
    p_i2c_para->ctl_id = DRV_FROM_AT(lchip) ? p_i2c_para->ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE : p_i2c_para->ctl_id;
    CTC_ERROR_RETURN(_sys_usw_peri_set_i2c_scan_para(lchip, p_i2c_para));

    return CTC_E_NONE;
}

/**
 @brief get i2c master for polling read
*/
int32
sys_usw_peri_get_i2c_scan_para(uint8 lchip, ctc_chip_i2c_scan_t* p_i2c_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_i2c_para);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1 < p_i2c_para->ctl_id)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_usw_peri_get_i2c_scan_para: out of bound! %u\n",
                         p_i2c_para->ctl_id);
        return CTC_E_INVALID_PARAM;
    }
    SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, p_i2c_para->ctl_id);
    p_i2c_para->ctl_id = DRV_FROM_AT(lchip) ? p_i2c_para->ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE : p_i2c_para->ctl_id;
    CTC_ERROR_RETURN(_sys_usw_peri_get_i2c_scan_para(lchip, p_i2c_para));

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "scan sfp, op_flag:0x%x, bitmap:0x%x addr:0x%x  offset:0x%x length:0x%x intreval:0x%x\n",
                     p_i2c_para->op_flag, p_i2c_para->slave_bitmap[0], p_i2c_para->dev_addr, p_i2c_para->offset, p_i2c_para->length, p_i2c_para->interval);

    return CTC_E_NONE;
}

/**
 @brief i2c master for polling read start
*/
int32
sys_usw_peri_set_i2c_scan_en(uint8 lchip, bool enable)
{
    uint32 cmd = 0;
    uint32 field_value = (TRUE == enable) ? 1 : 0;
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set Scan Enable enable:%d\n", ((TRUE == enable) ? 1 : 0));

    cmd = DRV_IOW(I2CMasterReadCtl0_t, I2CMasterReadCtl0_readEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    cmd = DRV_IOW(I2CMasterReadCtl1_t, I2CMasterReadCtl1_readEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    return CTC_E_NONE;
}

/**
 @brief get i2c master for polling read start
*/
int32
sys_usw_peri_get_i2c_scan_en(uint8 lchip, bool* enable)
{
    uint32 cmd = 0;
    uint32 field_value = 0;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(enable);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    cmd = DRV_IOR(I2CMasterReadCtl0_t, I2CMasterReadCtl0_readEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_value));

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get Scan Enable enable:%d\n", field_value);

    *enable = field_value;

    return CTC_E_NONE;
}

/**
 @brief interface for read i2c databuf, usual used for i2c master for polling read
*/
int32
sys_usw_peri_read_i2c_buf(uint8 lchip, ctc_chip_i2c_scan_read_t *p_i2c_scan_read)
{
    uint32 index = 0;
    uint32 cmd = 0;
    ds_t ds;
    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_i2c_scan_read);
    CTC_PTR_VALID_CHECK(p_i2c_scan_read->p_buf);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "read sfp buf, lchip:%d len:%d\n",
                                                lchip, p_i2c_scan_read->len);

    if (p_i2c_scan_read->len > SYS_CHIP_I2C_READ_MAX_LENGTH)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_usw_peri_read_i2c_buf: p_i2c_scan_read->len (%d) out of bound!\n", p_i2c_scan_read->len);
        return CTC_E_INVALID_PARAM;
    }

    if (MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1 < p_i2c_scan_read->ctl_id)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "sys_usw_peri_read_i2c_buf: ctl_id (%d) out of bound!\n", p_i2c_scan_read->ctl_id);
        return CTC_E_INVALID_PARAM;
    }

    if (TRUE != sys_usw_chip_is_local(lchip, p_i2c_scan_read->gchip))
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid Local chip id \n");
			return CTC_E_INVALID_CHIP_ID;

    }

    if (DRV_FROM_AT(lchip))
    {
        uint16 idx_offset = (p_i2c_scan_read->ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE) * SYS_CHIP_I2C_READ_MAX_LENGTH;
        SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, p_i2c_scan_read->ctl_id);
        cmd = DRV_IOR(I2CMasterDataMem_t, DRV_ENTRY_FLAG);

        /* I2CMasterDataMem, entry0~383 is for I2CMaster0, entry384~767 is for I2CMaster1 */
        for (index = 0; index < p_i2c_scan_read->len; index++)
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index + idx_offset, DRV_CMD_PP_EN(cmd), &ds));

            p_i2c_scan_read->p_buf[index] = GetI2CMasterDataMem(V, data_f, &ds);
        }
    }
    else
    {
        cmd = DRV_IOR(I2CMasterDataMem0_t + p_i2c_scan_read->ctl_id, DRV_ENTRY_FLAG);

        for (index = 0; index < p_i2c_scan_read->len; index++)
        {
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ds));

            p_i2c_scan_read->p_buf[index] = GetI2CMasterDataMem0(V, data_f, &ds);
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_set_i2c_clock(uint8 lchip, uint8 ctl_id, uint16 freq)
{
    uint32 cmd = 0;
    uint32 field_value = 0;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_MAX_VALUE_CHECK(ctl_id, MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((SDK_WORK_PLATFORM != 0) || (DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    field_value = MCHIP_CAP(SYS_CAP_I2C_REF_CLOCK) * 1000 / freq;
    SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, ctl_id);
    ctl_id = DRV_FROM_AT(lchip)?(ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE):ctl_id;
    if (0 == ctl_id)
    {
        cmd = DRV_IOW(I2CMasterCfg0_t, I2CMasterCfg0_clkDiv_f);
    }
    else
    {
        cmd = DRV_IOW(I2CMasterCfg1_t, I2CMasterCfg0_clkDiv_f);
    }
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_value));

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_i2c_clock(uint8 lchip, uint8 ctl_id, uint16* freq)
{
    uint32 cmd = 0;
    uint32 field_val = 0;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_MAX_VALUE_CHECK(ctl_id, MCHIP_CAP(SYS_CAP_I2C_CTL_NUM)-1);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((SDK_WORK_PLATFORM != 0) || (DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    SYS_PERI_I2C_MAP_LCHIP_BY_GPIO_ID(lchip, ctl_id);
    ctl_id = DRV_FROM_AT(lchip)?(ctl_id % SYS_PERI_I2C_CTRL_NUM_PER_CORE):ctl_id;
    if (0 == ctl_id)
    {
        cmd = DRV_IOR(I2CMasterCfg0_t, I2CMasterCfg0_clkDiv_f);
    }
    else
    {
        cmd = DRV_IOR(I2CMasterCfg1_t, I2CMasterCfg1_clkDiv_f);
    }
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_val));

    *freq = MCHIP_CAP(SYS_CAP_I2C_REF_CLOCK) * 1000 / field_val;

    return CTC_E_NONE;
}

#define __MAC_LED_INTERFACE__

int32
_sys_usw_peri_set_i2c_drv_cap(uint8 lchip, uint8 ctl_id, uint32 val)
{
    uint32 cmd = 0;
    I2CPadCtl_m i2c_pad_ctl;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set i2c drvive capaility: ctl_id %u value %u\n", ctl_id, val);

    if ((SDK_WORK_PLATFORM != 0) || (!DRV_FROM_TMM(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        CTC_MAX_VALUE_CHECK(ctl_id, 1);
        CTC_MAX_VALUE_CHECK(val, SYS_USW_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(I2CPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &i2c_pad_ctl));
        SetI2CPadCtl(V, pdrvMscl0_f + ctl_id*(I2CPadCtl_pdrvMscl1_f - I2CPadCtl_pdrvMscl0_f), &i2c_pad_ctl, val);
        SetI2CPadCtl(V, pdrvMsda0_f + ctl_id*(I2CPadCtl_pdrvMsda1_f - I2CPadCtl_pdrvMsda0_f), &i2c_pad_ctl, val);
        cmd = DRV_IOW(I2CPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &i2c_pad_ctl));
    }
    else if (DRV_FROM_AT(lchip))
    {
        CTC_MAX_VALUE_CHECK(ctl_id, 0);
        CTC_MAX_VALUE_CHECK(val, SYS_AT_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(I2CPadCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &i2c_pad_ctl));
        SetI2CPadCfg(V, cfgDcsScl_f, &i2c_pad_ctl, val);
        SetI2CPadCfg(V, cfgDcsSda_f, &i2c_pad_ctl, val);
        cmd = DRV_IOW(I2CPadCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &i2c_pad_ctl));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_peri_get_i2c_drv_cap(uint8 lchip, uint8 ctl_id, uint32* p_val)
{
    uint32 cmd = 0;
    I2CPadCtl_m i2c_pad_ctl;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get i2c drvive capaility: ctl_id %u\n", ctl_id);

    if ((SDK_WORK_PLATFORM != 0) || (!DRV_FROM_TMM(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        CTC_MAX_VALUE_CHECK(ctl_id, 1);
        cmd = DRV_IOR(I2CPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &i2c_pad_ctl));
        *p_val = GetI2CPadCtl(V, pdrvMscl0_f + ctl_id*(I2CPadCtl_pdrvMscl1_f - I2CPadCtl_pdrvMscl0_f), &i2c_pad_ctl);
    }
    else if (DRV_FROM_AT(lchip))
    {
        CTC_MAX_VALUE_CHECK(ctl_id, 0);
        cmd = DRV_IOR(I2CPadCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &i2c_pad_ctl));
        *p_val = GetI2CPadCfg(V, cfgDcsScl_f, &i2c_pad_ctl);
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get i2c drvive capaility: value %d\n", *p_val);

    return CTC_E_NONE;
}

/**
 @brief mac led interface
*/
int32
sys_usw_peri_set_mac_led_mode(uint8 lchip, ctc_chip_led_para_t* p_led_para, ctc_chip_mac_led_type_t led_type, uint8 inner)
{
    CTC_PTR_VALID_CHECK(p_led_para);
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(NULL != MCHIP_PERI(lchip)->peri_set_mac_led_mode)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_mac_led_mode(lchip, p_led_para, led_type, inner));
    }
    return CTC_E_NONE;
}

/**
 @brief mac led interface for mac and led mapping
*/
int32
sys_usw_peri_set_mac_led_mapping(uint8 lchip, ctc_chip_mac_led_mapping_t* p_led_map)
{
    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_led_map);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac num:%d \n", p_led_map->mac_led_num);
    if(NULL != MCHIP_PERI(lchip)->peri_set_mac_led_mapping)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_mac_led_mapping(lchip, p_led_map));
    }
    return CTC_E_NONE;
}

/**
 @brief begin mac led function
*/
int32
sys_usw_peri_set_mac_led_en(uint8 lchip, bool enable)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "mac led Enable enable:%d\n", ((TRUE == enable) ? 1 : 0));
    if(NULL != MCHIP_PERI(lchip)->peri_set_mac_led_en)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_mac_led_en(lchip, enable));
    }
    return CTC_E_NONE;
}

/**
 @brief get mac led function
*/
int32
sys_usw_peri_get_mac_led_en(uint8 lchip, bool* enable)
{
    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(enable);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(NULL != MCHIP_PERI(lchip)->peri_get_mac_led_en)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_get_mac_led_en(lchip, enable));
    }
    return CTC_E_NONE;
}

int32
sys_usw_peri_set_mac_led_clock(uint8 lchip, uint16 freq)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((SDK_WORK_PLATFORM != 0) || (DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    if(NULL != MCHIP_PERI(lchip)->peri_set_mac_led_clock)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_mac_led_clock(lchip, freq));
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_mac_led_clock(uint8 lchip, uint16* freq)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((SDK_WORK_PLATFORM != 0) || (DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    if(NULL != MCHIP_PERI(lchip)->peri_get_mac_led_clock)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_get_mac_led_clock(lchip, freq));
    }

    return CTC_E_NONE;
}

STATIC int32
sys_usw_peri_set_macled_blink_interval(uint8 lchip, uint32* interval)
{

    uint32 cmd = 0;
    uint32 value = 0;
    uint8 ctl_id = 0;
    uint8 ctl_num = 0;

    if(SDK_WORK_PLATFORM != 0)
    {
        return CTC_E_NOT_SUPPORT;
    }
    CTC_MAX_VALUE_CHECK(*interval,SYS_USW_MACLED_BLINK_INTERVAL_MAX);
    value = *interval;
    /* sampleInterval is 6.5 times as refreshInterval,blinkOffInterval is 5.2 times as refreshInterval */
    if(DRV_IS_DUET2(lchip))
    {
        cmd = DRV_IOW(LedBlinkCfg0_t, LedBlinkCfg0_blinkOffInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        cmd = DRV_IOW(LedBlinkCfg1_t, LedBlinkCfg1_blinkOffInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        cmd = DRV_IOW(LedBlinkCfg0_t, LedBlinkCfg0_blinkOnInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        cmd = DRV_IOW(LedBlinkCfg1_t, LedBlinkCfg1_blinkOnInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        value = *interval / 5;
        cmd = DRV_IOW(LedRefreshInterval0_t, LedRefreshInterval0_refreshInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        cmd = DRV_IOW(LedRefreshInterval1_t, LedRefreshInterval1_refreshInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        value = value * 6 + value / 2;
        cmd = DRV_IOW(LedSampleInterval0_t, LedSampleInterval0_sampleInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        cmd = DRV_IOW(LedSampleInterval1_t, LedSampleInterval1_sampleInterval_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    }
    else
    {
        ctl_num = (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) ? 2 : 1;
        for (ctl_id = 0; ctl_id < ctl_num; ctl_id++)
        {
            value = *interval;
            cmd = DRV_IOW(LedBlinkCfg_t, LedBlinkCfg_blinkOffInterval_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &value));
            cmd = DRV_IOW(LedBlinkCfg_t, LedBlinkCfg_blinkOnInterval_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &value));
            value = *interval / 5;
            cmd = DRV_IOW(LedRefreshInterval_t, LedRefreshInterval_refreshInterval_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &value));
            value = value * 6 + value / 2;
            cmd = DRV_IOW(LedSampleInterval_t, LedSampleInterval_sampleInterval_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, ctl_id, cmd, &value));
        }
    }

    return CTC_E_NONE;
}

STATIC int32
sys_usw_peri_get_macled_blink_interval(uint8 lchip, uint32* interval)
{
    uint32 cmd = 0;
    uint32 table_id = 0;

    if(SDK_WORK_PLATFORM != 0)
    {
        return CTC_E_NOT_SUPPORT;
    }
    table_id = DRV_IS_DUET2(lchip)?LedBlinkCfg0_t:LedBlinkCfg_t;
    cmd = DRV_IOR(table_id, LedBlinkCfg0_blinkOffInterval_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, interval));

    return CTC_E_NONE;
}

int32
_sys_usw_peri_set_mac_led_drv_cap(uint8 lchip, uint32 val)
{
    uint32 cmd = 0;
    MacLedPadCtl_m led_pad_ctl;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set led drvive capaility: value %u\n", val);

    if ((SDK_WORK_PLATFORM != 0) || (!DRV_FROM_TMM(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        CTC_MAX_VALUE_CHECK(val, SYS_USW_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(MacLedPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &led_pad_ctl));
        SetMacLedPadCtl(V, pdrvLedClk0_f, &led_pad_ctl, val);
        SetMacLedPadCtl(V, pdrvLedData0_f, &led_pad_ctl, val);
        SetMacLedPadCtl(V, pdrvLedClk1_f, &led_pad_ctl, val);
        SetMacLedPadCtl(V, pdrvLedData1_f, &led_pad_ctl, val);
        cmd = DRV_IOW(MacLedPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &led_pad_ctl));
    }
    if (DRV_FROM_AT(lchip))
    {
        CTC_MAX_VALUE_CHECK(val, SYS_AT_PERI_MAX_DRV_CAP);
        cmd = DRV_IOR(LedPadCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &led_pad_ctl));
        SetLedPadCfg(V, cfgDcsLedClk_f, &led_pad_ctl, val);
        SetLedPadCfg(V, cfgDcsLedClk_f, &led_pad_ctl, val);
        cmd = DRV_IOW(LedPadCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &led_pad_ctl));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_peri_get_mac_led_drv_cap(uint8 lchip, uint32* p_val)
{
    uint32 cmd = 0;
    MacLedPadCtl_m led_pad_ctl;

    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if ((SDK_WORK_PLATFORM != 0) || (!DRV_FROM_TMM(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        cmd = DRV_IOR(MacLedPadCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &led_pad_ctl));
        *p_val = GetMacLedPadCtl(V, pdrvLedClk0_f, &led_pad_ctl);
    }
    if (DRV_FROM_AT(lchip))
    {
        cmd = DRV_IOR(LedPadCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0,  DRV_CMD_PP_EN(cmd), &led_pad_ctl));
        *p_val = GetLedPadCfg(V, cfgDcsLedClk_f, &led_pad_ctl);
    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Get led drvive capaility: value %u\n", *p_val);

    return CTC_E_NONE;
}

#define __GPIO_INTERFACE__
/**
 @brief gpio interface
*/
int32
sys_usw_peri_set_gpio_mode(uint8 lchip, uint8 gpio_id, ctc_chip_gpio_mode_t mode)
{
    SYS_PERI_INIT_CHECK(lchip);
    if(NULL != MCHIP_PERI(lchip)->peri_set_gpio_mode)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_gpio_mode(lchip, gpio_id, mode));
    }
    return CTC_E_NONE;
}

/**
 @brief gpio output
*/
int32
sys_usw_peri_set_gpio_output(uint8 lchip, uint8 gpio_id, uint8 out_para)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "set gpio out, gpio_id:%d out_para:%d\n", gpio_id, out_para);
    if(NULL != MCHIP_PERI(lchip)->peri_set_gpio_output)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_gpio_output(lchip, gpio_id, out_para));
    }
    return CTC_E_NONE;
}


/**
 @brief gpio input
*/
int32
sys_usw_peri_get_gpio_input(uint8 lchip, uint8 gpio_id, uint8* in_value)
{
    SYS_PERI_INIT_CHECK(lchip);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(NULL != MCHIP_PERI(lchip)->peri_get_gpio_input)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_get_gpio_input(lchip, gpio_id, in_value));
    }
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "get gpio in, gpio_id:%d in_para:%d\n", gpio_id, *in_value);

    return CTC_E_NONE;
}

int32
sys_usw_peri_set_gpio_cfg(uint8 lchip, ctc_chip_gpio_cfg_t* p_cfg)
{
    uint32 cmd = 0;
    uint32 tbl_debce_id = 0;
    uint32 field_debce_id = 0;
    uint32 field_debce_val = 0;
    uint32 tbl_level_id = 0;
    uint32 field_level_id = 0;
    uint32 field_level_val = 0;
    uint32 gpio_act_id = 0;
    uint8 gpio_id = 0;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_cfg);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "set gpio cfg, gpio_id:%d debounce:%d level_edge_val: %d\n", gpio_id, p_cfg->debounce_en, p_cfg->level_edge_val);

    if (!DRV_IS_TSINGMA(lchip) && !DRV_IS_AT(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    gpio_id = p_cfg->gpio_id;
    if (p_cfg->gpio_id >= SYS_PERI_HS_MAX_GPIO_ID)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "gpio_id:%d over max gpio id\n", gpio_id);
        return CTC_E_INVALID_PARAM;
    }

    SYS_PERI_GPIO_MAP_LCHIP_BY_GPIO_ID(lchip, p_cfg->gpio_id);
    if (DRV_FROM_AT(lchip))
    {
        gpio_act_id = gpio_id % SYS_PERI_GPIO_NUM_PER_CORE;
        tbl_debce_id = GpioDebEn_t;
        field_debce_id = GpioDebEn_cfgDebEn_f;
        tbl_level_id = GpioIntrLevel_t;
        field_level_id = GpioIntrLevel_cfgIntrLevel_f;
    }
    else
    {
        if (SYS_PERI_GPIO_IS_HS(gpio_id))
        {
            gpio_act_id = gpio_id-SYS_PERI_MAX_GPIO_ID;
            tbl_debce_id = GpioHsDebCtl_t;
            field_debce_id = GpioHsDebCtl_cfgHsDebEn_f;
            tbl_level_id = GpioHsIntrLevel_t;
            field_level_id = GpioHsIntrLevel_cfgHsIntrLevel_f;
        }
        else
        {
            gpio_act_id = gpio_id;
            tbl_debce_id = GpioDebCtl_t;
            field_debce_id = GpioDebCtl_cfgDebEn_f;
            tbl_level_id = GpioIntrLevel_t;
            field_level_id = GpioIntrLevel_cfgIntrLevel_f;
        }
    }

    cmd = DRV_IOR(tbl_debce_id, field_debce_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_debce_val));
    cmd = DRV_IOR(tbl_level_id, field_level_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_level_val));

    if (p_cfg->debounce_en)
    {
        CTC_BIT_SET(field_debce_val, gpio_act_id);
    }
    else
    {
        CTC_BIT_UNSET(field_debce_val, gpio_act_id);
    }

    if (p_cfg->level_edge_val)
    {
        CTC_BIT_SET(field_level_val, gpio_act_id);
    }
    else
    {
        CTC_BIT_UNSET(field_level_val, gpio_act_id);
    }

    cmd = DRV_IOW(tbl_debce_id, field_debce_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_debce_val));
    cmd = DRV_IOW(tbl_level_id, field_level_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_level_val));

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_gpio_cfg(uint8 lchip, ctc_chip_gpio_cfg_t* p_cfg)
{
    uint32 cmd = 0;
    uint32 tbl_debce_id = 0;
    uint32 field_debce_id = 0;
    uint32 field_debce_val = 0;
    uint32 tbl_level_id = 0;
    uint32 field_level_id = 0;
    uint32 field_level_val = 0;
    uint32 gpio_act_id = 0;
    uint8 gpio_id = 0;

    SYS_PERI_INIT_CHECK(lchip);
    CTC_PTR_VALID_CHECK(p_cfg);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (!DRV_IS_TSINGMA(lchip) && !DRV_IS_AT(lchip))
    {
        return CTC_E_NOT_SUPPORT;
    }
    gpio_id = p_cfg->gpio_id;
    if (p_cfg->gpio_id >= SYS_PERI_HS_MAX_GPIO_ID)
    {
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "gpio_id:%d over max gpio id\n", gpio_id);
        return CTC_E_INVALID_PARAM;
    }

    SYS_PERI_GPIO_MAP_LCHIP_BY_GPIO_ID(lchip, p_cfg->gpio_id);
    if (SYS_PERI_GPIO_IS_HS(gpio_id))
    {
        gpio_act_id = gpio_id-SYS_PERI_MAX_GPIO_ID;
        tbl_debce_id = GpioHsDebCtl_t;
        field_debce_id = GpioHsDebCtl_cfgHsDebEn_f;
        tbl_level_id = GpioHsIntrLevel_t;
        field_level_id = GpioHsIntrLevel_cfgHsIntrLevel_f;
    }
    else if (DRV_FROM_AT(lchip))
    {
        gpio_act_id = gpio_id % SYS_PERI_GPIO_NUM_PER_CORE;
        tbl_debce_id = GpioDebEn_t;
        field_debce_id = GpioDebEn_cfgDebEn_f;
        tbl_level_id = GpioIntrLevel_t;
        field_level_id = GpioIntrLevel_cfgIntrLevel_f;
    }
    else
    {
        gpio_act_id = gpio_id;
        tbl_debce_id = GpioDebCtl_t;
        field_debce_id = GpioDebCtl_cfgDebEn_f;
        tbl_level_id = GpioIntrLevel_t;
        field_level_id = GpioIntrLevel_cfgIntrLevel_f;
    }

    cmd = DRV_IOR(tbl_debce_id, field_debce_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_debce_val));
    cmd = DRV_IOR(tbl_level_id, field_level_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &field_level_val));

    if (CTC_IS_BIT_SET(field_debce_val, gpio_act_id))
    {
        p_cfg->debounce_en = 1;
    }
    else
    {
        p_cfg->debounce_en = 0;
    }

    if (CTC_IS_BIT_SET(field_level_val, gpio_act_id))
    {
        p_cfg->level_edge_val = 1;
    }
    else
    {
        p_cfg->level_edge_val = 0;
    }

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "get gpio cfg, gpio_id:%d debounce:%d level_edge_val: %d\n", gpio_id, p_cfg->debounce_en, p_cfg->level_edge_val);

    return CTC_E_NONE;
}

#define __OTHER_INTERFACE__

int32
sys_usw_peri_set_dlb_chan_type(uint8 lchip, uint16 chan_id)
{
    uint32 value = 0;
    uint32 cmd = 0;
    uint16 lport = 0;
    uint32 port_type = 0;
    uint32 speed_mode = 0;
    uint8 gchip_id = 0;
    uint32 pp_id = 0;
    uint32 dp_id = 0;
    uint32 sub_chan = 0;
    uint32 index = 0;
    uint8 step = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsEpeHeaderEditChanLoadWeight_m chan_load_weight;
    DsErmChanSizeWeight_m chan_size_weight;
    SYS_PERI_INIT_CHECK(lchip);
    /* get local phy port by chan_id */
    lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, chan_id);

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip_id));
    dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, lport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SPEED_MODE, (void *)&speed_mode));
    
    if ((port_type == SYS_DMPS_NETWORK_PORT) || (port_type == SYS_DMPS_CPUMAC_NETWORK_PORT))
    {
        switch (speed_mode)
        {
            case CTC_PORT_SPEED_10M:
            case CTC_PORT_SPEED_100M:
            case CTC_PORT_SPEED_1G:
            case CTC_PORT_SPEED_2G5:
                value = 0;  /* 1G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_5G:
                value = 1;  /* 5G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_10G:
                value = 2;  /* 10G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_20G:
                value = 3;  /* 20G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_25G:
                value = 4;  /* 25G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_40G:
                value = 5;  /* 40G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_50G:
                value = 6;  /* 50G, get channel type by datapath */
                break;

            case CTC_PORT_SPEED_100G:
                value = 7;  /* 100G, get channel type by datapath */
                break;
            default:
                value = 7;
                break;
        }

        if(DRV_FROM_AT(lchip))
        {
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PP_ID, &pp_id));
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_DP_ID, &dp_id));
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_SUB_CHAN_ID, &sub_chan));
            step = DsEpeHeaderEditChanLoadWeight_g_1_profileId_f - DsEpeHeaderEditChanLoadWeight_g_0_profileId_f;
            cmd = DRV_IOR(DsEpeHeaderEditChanLoadWeight_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip + pp_id, sub_chan, DRV_CMD_PP_EN(cmd), &chan_load_weight));
            SetDsEpeHeaderEditChanLoadWeight(V, g_0_profileId_f + step * dp_id, &chan_load_weight, value);
            cmd = DRV_IOW(DsEpeHeaderEditChanLoadWeight_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip + pp_id, sub_chan, DRV_CMD_PP_EN(cmd), &chan_load_weight));
            
            index = (sub_chan < 16) ? ((sub_chan >> 3) + (pp_id << 2) + (dp_id << 1))
                                     : (32 + (pp_id << 1) + dp_id);
            cmd = DRV_IOR(DsErmChanSizeWeight_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &chan_size_weight));
            SetDsErmChanSizeWeight(V, g_0_profileId_f + (sub_chan & 0x7), &chan_size_weight, value);
            cmd = DRV_IOW(DsErmChanSizeWeight_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &chan_size_weight));
        }
        else if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            cmd = DRV_IOW(LagDlbChanQueueDepthType_t, LagDlbChanQueueDepthType_gChanId_0_qDepthThresholdWeightProfileId_f + SYS_USW_CHANNEL_ENCODE(chan_id));
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

            cmd = DRV_IOW(LagDlbChanLoadType_t, LagDlbChanLoadType_gChanId_0_loadThresholdWeightProfileId_f + SYS_USW_CHANNEL_ENCODE(chan_id));
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        }
        else
        {
            cmd = DRV_IOW(DlbChanMaxLoadType_t, DlbChanMaxLoadType_loadType_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &value));
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_set_global_eee_en(uint8 lchip, uint32* enable)
{
#if 0
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 tbl_id = 0;

    /* cfg NetTxMiscCtl */
    value = enable?1:0;

    tbl_id = NetTxMiscCtl0_t;
    cmd = DRV_IOW(tbl_id, NetTxMiscCtl0_eeeCtlEnable_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    tbl_id = NetTxMiscCtl1_t;
    cmd = DRV_IOW(tbl_id, NetTxMiscCtl0_eeeCtlEnable_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
#endif
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_peri_set_mem_scan_mode(uint8 lchip, ctc_chip_mem_scan_cfg_t* p_cfg)
{

    drv_ser_scan_info_t ecc_scan_info;

    if(drv_ser_get_cfg(lchip, DRV_SER_CFG_TYPE_SCAN_MODE, NULL))
    {
        CTC_ERROR_RETURN(sys_usw_dma_set_tcam_scan_mode(lchip, p_cfg->tcam_scan_mode, p_cfg->tcam_scan_interval));
    }

    ecc_scan_info.type = DRV_SER_SCAN_TYPE_TCAM;
    ecc_scan_info.mode =p_cfg->tcam_scan_mode;
    ecc_scan_info.scan_interval = p_cfg->tcam_scan_interval;
    drv_ser_set_cfg(lchip, DRV_SER_CFG_TYPE_SCAN_MODE,&ecc_scan_info);

    ecc_scan_info.type = DRV_SER_SCAN_TYPE_SBE;
    ecc_scan_info.mode = p_cfg->sbe_scan_mode;
    ecc_scan_info.scan_interval = p_cfg->sbe_scan_interval;
    drv_ser_set_cfg(lchip, DRV_SER_CFG_TYPE_SCAN_MODE,&ecc_scan_info);

    return CTC_E_NONE;

}

STATIC int32
_sys_usw_peri_get_mem_scan_mode(uint8 lchip, ctc_chip_mem_scan_cfg_t* p_cfg)
{


    drv_ser_scan_info_t ecc_scan_info;

    ecc_scan_info.type = DRV_SER_SCAN_TYPE_TCAM;
    drv_ser_get_cfg(lchip, DRV_SER_CFG_TYPE_SCAN_MODE,&ecc_scan_info);
    p_cfg->tcam_scan_mode =  ecc_scan_info.mode;
    p_cfg->tcam_scan_interval =  ecc_scan_info.scan_interval;

    ecc_scan_info.type = DRV_SER_SCAN_TYPE_SBE;
    drv_ser_get_cfg(lchip, DRV_SER_CFG_TYPE_SCAN_MODE,&ecc_scan_info);
    p_cfg->sbe_scan_mode =  ecc_scan_info.mode;
    p_cfg->sbe_scan_interval =  ecc_scan_info.scan_interval;


    return CTC_E_NONE;
}
#ifdef CTC_HW_RESET_EN
void _sys_usw_peri_reset_hw_thread(void* p_param)
{
    int32 ret = CTC_E_NONE;
    uint8 lchip = (uintptr)p_param;
    uint8 intr_en = 0;
    uint8 lchip_start = 0;
    uint8 lchip_end = 0;
    
    lchip_start = SYS_PP_BASE(lchip);
    lchip_end = lchip_start + SYS_PP_NUM(lchip);
    
    for (lchip=lchip_start; lchip<lchip_end; lchip++)
    {
        ret = drv_ser_set_cfg(lchip, DRV_SER_CFG_TYPE_HW_RESER_EN, NULL);
        if(ret)
        {
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "SDB/SER init incorrectly, or HW reset fail!\n");
        }
        SYS_LCHIP_CHECK_ACTIVE_IN_THREAD(lchip);
        ret = sys_usw_interrupt_get_group_en(lchip, &intr_en);
        if(0 == intr_en)
        {
            sys_usw_interrupt_set_group_en(lchip, TRUE);
        }
    }
    p_usw_peri_master[lchip_start]->hw_reset_status = (ret) ? CTC_CHIP_HW_RESET_DONE_ERROR : CTC_CHIP_HW_RESET_DONE;
    return;
}

STATIC int32
_sys_usw_peri_reset_hw(uint8 lchip, void* p_data)
{
    uint32 cpu_mask;
    int32  ret = 0;
    
    if(p_usw_peri_master[lchip]->hw_reset_status == CTC_CHIP_HW_RESET_PROCESSING)
    {
        return CTC_E_HW_BUSY;
    }

    /*first destroy the last thread*/
    if(p_usw_peri_master[lchip]->p_hw_reset_task)
    {
        sal_task_destroy(p_usw_peri_master[lchip]->p_hw_reset_task);
    }
    
    p_usw_peri_master[lchip]->hw_reset_status = CTC_CHIP_HW_RESET_PROCESSING;
    cpu_mask = sys_usw_chip_get_affinity(lchip, 0);
    ret = sys_usw_task_create(lchip,&p_usw_peri_master[lchip]->p_hw_reset_task, "hw reset thread",
                          SAL_DEF_TASK_STACK_SIZE, SAL_TASK_PRIO_DEF,SAL_TASK_TYPE_OTHERS,cpu_mask, _sys_usw_peri_reset_hw_thread, (void*)(uintptr)lchip);
    
    if(ret)
    {
        p_usw_peri_master[lchip]->hw_reset_status = CTC_CHIP_HW_RESET_DONE_ERROR;
        SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "Create hw reset thread fail!!!\n");
        return CTC_E_INIT_FAIL;
    }

    return CTC_E_NONE;
}
#endif
/**
 @brief begin memory BIST function
*/
STATIC int32
_sys_usw_chip_set_mem_bist(uint8 lchip, ctc_chip_mem_bist_t* p_value)
{
    int32 ret = 0;
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_value);

    if (NULL == MCHIP_MISC(lchip)->mem_bist_set)
    {
        return CTC_E_NOT_SUPPORT;
    }

    if (1 == SDK_WORK_PLATFORM)
    {
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(sys_usw_chip_set_active(lchip, FALSE));
    drv_set_warmboot_status(lchip, 1);

     /*cb*/
    CTC_ERROR_GOTO(MCHIP_MISC(lchip)->mem_bist_set(lchip, (void*)p_value), ret, error_return);

error_return:
    drv_set_warmboot_status(lchip, 0);
    CTC_ERROR_RETURN(sys_usw_chip_set_active(lchip, TRUE));

    return ret;

}

int32
sys_usw_peri_set_clock(uint8 lchip, ctc_chip_peri_clock_t* p_clock)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_clock->type)
    {
        case CTC_CHIP_PERI_MDIO_TYPE:
            CTC_ERROR_RETURN(sys_usw_peri_set_mdio_clock(lchip, p_clock->mdio_type, p_clock->clock_val));
            break;
        case CTC_CHIP_PERI_I2C_TYPE:
            CTC_ERROR_RETURN(sys_usw_peri_set_i2c_clock(lchip, p_clock->ctl_id, p_clock->clock_val));
            break;
        case CTC_CHIP_PERI_MAC_LED_TYPE:
            CTC_ERROR_RETURN(sys_usw_peri_set_mac_led_clock(lchip, p_clock->clock_val));
            break;
        default:
            return CTC_E_INVALID_PARAM;
            break;
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_clock(uint8 lchip, ctc_chip_peri_clock_t* p_clock)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_clock->type)
    {
        case CTC_CHIP_PERI_MDIO_TYPE:
            CTC_ERROR_RETURN(sys_usw_peri_get_mdio_clock(lchip, p_clock->mdio_type, &p_clock->clock_val));
            break;
        case CTC_CHIP_PERI_I2C_TYPE:
            CTC_ERROR_RETURN(sys_usw_peri_get_i2c_clock(lchip, p_clock->ctl_id, &p_clock->clock_val));
            break;
        case CTC_CHIP_PERI_MAC_LED_TYPE:
            CTC_ERROR_RETURN(sys_usw_peri_get_mac_led_clock(lchip, &p_clock->clock_val));
            break;
        default:
            return CTC_E_INVALID_PARAM;
            break;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_peri_set_drv_cap(uint8 lchip, ctc_chip_peri_drv_t* p_drv_cap)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_drv_cap->type)
    {
        case CTC_CHIP_PERI_MDIO_TYPE:
            CTC_ERROR_RETURN(_sys_usw_peri_set_mdio_drv_cap(lchip, p_drv_cap->bus, p_drv_cap->val));
            break;
        case CTC_CHIP_PERI_I2C_TYPE:
            CTC_ERROR_RETURN(_sys_usw_peri_set_i2c_drv_cap(lchip, p_drv_cap->ctl_id, p_drv_cap->val));
            break;
        case CTC_CHIP_PERI_MAC_LED_TYPE:
            CTC_ERROR_RETURN(_sys_usw_peri_set_mac_led_drv_cap(lchip, p_drv_cap->val));
            break;
        default:
            return CTC_E_INVALID_PARAM;
            break;
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_drv_cap(uint8 lchip, ctc_chip_peri_drv_t* p_drv_cap)
{
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_drv_cap->type)
    {
        case CTC_CHIP_PERI_MDIO_TYPE:
            CTC_ERROR_RETURN(_sys_usw_peri_get_mdio_drv_cap(lchip, p_drv_cap->bus, &p_drv_cap->val));
            break;
        case CTC_CHIP_PERI_I2C_TYPE:
            CTC_ERROR_RETURN(_sys_usw_peri_get_i2c_drv_cap(lchip, p_drv_cap->ctl_id, &p_drv_cap->val));
            break;
        case CTC_CHIP_PERI_MAC_LED_TYPE:
            CTC_ERROR_RETURN(_sys_usw_peri_get_mac_led_drv_cap(lchip, &p_drv_cap->val));
            break;
        default:
            return CTC_E_INVALID_PARAM;
            break;
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_set_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    ctc_chip_gpio_params_t* p_gpio_param = NULL;
    ctc_chip_gpio_cfg_t* p_gpio_cfg = NULL;

    CTC_PTR_VALID_CHECK(p_value);
    SYS_PERI_INIT_CHECK(lchip);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "lchip:%d chip_prop:0x%x \n", lchip, chip_prop);


    switch(chip_prop)
    {
        case CTC_CHIP_PROP_EEE_EN:
            CTC_ERROR_RETURN(_sys_usw_peri_set_global_eee_en(lchip, (uint32*)p_value));
            break;
        case CTC_CHIP_MAC_LED_EN:
            CTC_ERROR_RETURN(sys_usw_peri_set_mac_led_en(lchip, *((bool *)p_value)));
            break;
        case CTC_CHIP_PROP_MEM_SCAN:
            CTC_ERROR_RETURN(_sys_usw_peri_set_mem_scan_mode(lchip, p_value));
            break;
        case CTC_CHIP_PROP_RESET_HW:
            #ifdef CTC_HW_RESET_EN
            CTC_ERROR_RETURN(_sys_usw_peri_reset_hw(lchip, p_value));
            #else
            return CTC_E_NOT_SUPPORT;
            #endif
            break;
        case CTC_CHIP_PROP_GPIO_MODE:
            p_gpio_param = (ctc_chip_gpio_params_t*)p_value;
            CTC_ERROR_RETURN(sys_usw_peri_set_gpio_mode(lchip,
                                    p_gpio_param->gpio_id, p_gpio_param->value));
            break;
        case CTC_CHIP_PROP_GPIO_OUT:
            p_gpio_param = (ctc_chip_gpio_params_t*)p_value;
            CTC_ERROR_RETURN(sys_usw_peri_set_gpio_output(lchip,
                                    p_gpio_param->gpio_id, p_gpio_param->value));
            break;
        case CTC_CHIP_PROP_GPIO_CFG:
            p_gpio_cfg = (ctc_chip_gpio_cfg_t*)p_value;
            CTC_ERROR_RETURN(sys_usw_peri_set_gpio_cfg(lchip, p_gpio_cfg));
            break;
        case CTC_CHIP_PROP_MEM_BIST:
            CTC_ERROR_RETURN(_sys_usw_chip_set_mem_bist(lchip, (ctc_chip_mem_bist_t*)p_value));
            break;
        case CTC_CHIP_PHY_SCAN_EN:
            CTC_ERROR_RETURN(sys_usw_peri_set_phy_scan_en(lchip, *((bool*)p_value)));
            break;
        case CTC_CHIP_PHY_SCAN_PARA:
            CTC_ERROR_RETURN(sys_usw_peri_set_phy_scan_para(lchip, (ctc_chip_phy_scan_ctrl_t*)p_value));
            break;
        case CTC_CHIP_I2C_SCAN_EN:
            CTC_ERROR_RETURN(sys_usw_peri_set_i2c_scan_en(lchip, *((bool*)p_value)));
            break;
        case CTC_CHIP_I2C_SCAN_PARA:
            CTC_ERROR_RETURN(sys_usw_peri_set_i2c_scan_para(lchip, (ctc_chip_i2c_scan_t*)p_value));
            break;
        case CTC_CHIP_PROP_PERI_CLOCK:
            CTC_ERROR_RETURN(sys_usw_peri_set_clock(lchip, (ctc_chip_peri_clock_t*)p_value));
            break;
        case CTC_CHIP_PROP_MAC_LED_BLINK_INTERVAL:
            CTC_ERROR_RETURN(sys_usw_peri_set_macled_blink_interval(lchip, (uint32*)p_value));
            break;
        case CTC_CHIP_PROP_PHY_SAMPLE_OFFSET:
            CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_phy_sample_offset(lchip, (ctc_chip_mdio_para_t*)p_value));
            break;
        case CTC_CHIP_PROP_PHY_SAMPLE_EDGE:
            CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_phy_sample_edge(lchip, (ctc_chip_mdio_para_t*)p_value));
            break;
        case CTC_CHIP_PROP_IO_WR_DIS:
            CTC_ERROR_RETURN(drv_set_warmboot_status(lchip, (*(uint32*)p_value)?CTC_WB_STATUS_RELOADING:CTC_WB_STATUS_DONE));
            break;
        case CTC_CHIP_PROP_MDC_VOLTAGE_MODE:
            CTC_ERROR_RETURN(_sys_usw_peri_set_mdc_voltage_mode(lchip, *((uint32*)p_value)));
            break;
        case CTC_CHIP_PROP_CPU_LED_EN:
            if (!DRV_FROM_TMM(lchip))
            {
                return CTC_E_NOT_SUPPORT;
            }
            p_usw_peri_master[lchip]->is_cpu_led = *(bool*)p_value;
            break;
        case CTC_CHIP_PROP_PERI_DRV_CAP:
            CTC_ERROR_RETURN(_sys_usw_peri_set_drv_cap(lchip, (ctc_chip_peri_drv_t*)p_value));
            break;
        case CTC_CHIP_PROP_SENSOR_MONITOR:
            if(DRV_FROM_AT(lchip))
            {
                CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_set_sensor_monitor(lchip, (ctc_chip_sensor_monitor_t*)p_value));
            }
            else
            {
                return CTC_E_NOT_SUPPORT;
            }
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_property(uint8 lchip, ctc_chip_property_t chip_prop, void* p_value)
{
    ctc_chip_gpio_params_t* p_gpio_param = NULL;
    ctc_chip_gpio_cfg_t* p_gpio_cfg = NULL;
    int32 ret = CTC_E_NONE;
    CTC_PTR_VALID_CHECK(p_value);

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    PERI_LOCK(lchip);
    switch(chip_prop)
    {

        case CTC_CHIP_PROP_DEVICE_INFO:
            CTC_ERROR_GOTO(sys_usw_chip_get_device_info(lchip, (ctc_chip_device_info_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_MAC_LED_EN:
            CTC_ERROR_GOTO(sys_usw_peri_get_mac_led_en(lchip, (bool*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_MEM_SCAN:
            CTC_ERROR_GOTO(_sys_usw_peri_get_mem_scan_mode(lchip, p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_GPIO_IN:
            p_gpio_param = (ctc_chip_gpio_params_t*)p_value;
            CTC_ERROR_GOTO(sys_usw_peri_get_gpio_input(lchip,
                                    p_gpio_param->gpio_id, &(p_gpio_param->value)), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_GPIO_CFG:
            p_gpio_cfg = (ctc_chip_gpio_cfg_t*)p_value;
            CTC_ERROR_GOTO(sys_usw_peri_get_gpio_cfg(lchip, p_gpio_cfg), ret, error_roll_back);
            break;
        case CTC_CHIP_PHY_SCAN_EN:
            CTC_ERROR_GOTO(sys_usw_peri_get_phy_scan_en(lchip, (bool*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PHY_SCAN_PARA:
            CTC_ERROR_GOTO(sys_usw_peri_get_phy_scan_para(lchip, (ctc_chip_phy_scan_ctrl_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_I2C_SCAN_EN:
            CTC_ERROR_GOTO(sys_usw_peri_get_i2c_scan_en(lchip, (bool*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_I2C_SCAN_PARA:
            CTC_ERROR_GOTO(sys_usw_peri_get_i2c_scan_para(lchip, (ctc_chip_i2c_scan_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_PERI_CLOCK:
            CTC_ERROR_GOTO(sys_usw_peri_get_clock(lchip, (ctc_chip_peri_clock_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_MAC_LED_BLINK_INTERVAL:
            CTC_ERROR_GOTO(sys_usw_peri_get_macled_blink_interval(lchip, (uint32*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_PHY_SAMPLE_OFFSET:
            CTC_ERROR_GOTO(MCHIP_PERI(lchip)->peri_get_phy_sample_offset(lchip, (ctc_chip_mdio_para_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_PHY_SAMPLE_EDGE:
            CTC_ERROR_GOTO(MCHIP_PERI(lchip)->peri_get_phy_sample_edge(lchip, (ctc_chip_mdio_para_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_SENSOR:
            if(NULL != MCHIP_PERI(lchip)->peri_get_chip_sensor)
            {
                CTC_ERROR_GOTO(MCHIP_PERI(lchip)->peri_get_chip_sensor(lchip, p_value), ret, error_roll_back);
            }
            break;
        case CTC_CHIP_PROP_IO_WR_DIS:
            {
                uint32 wb_status = 0;
                CTC_ERROR_GOTO(drv_get_warmboot_status(lchip, &wb_status), ret, error_roll_back);
                *(uint32*)p_value = (CTC_WB_STATUS_RELOADING==wb_status)?1:0;
            }
            break;
        case CTC_CHIP_PROP_RESET_HW:
            *(uint32*)p_value = p_usw_peri_master[lchip]?p_usw_peri_master[lchip]->hw_reset_status:0;
            break;
        case CTC_CHIP_PROP_MDC_VOLTAGE_MODE:
            CTC_ERROR_GOTO(_sys_usw_peri_get_mdc_voltage_mode(lchip, (uint32*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_CPU_LED_EN:
            *(bool*)p_value = p_usw_peri_master[lchip]->is_cpu_led;
            break;
        case CTC_CHIP_PROP_PERI_DRV_CAP:
            CTC_ERROR_GOTO(sys_usw_peri_get_drv_cap(lchip, (ctc_chip_peri_drv_t*)p_value), ret, error_roll_back);
            break;
        case CTC_CHIP_PROP_SENSOR_MONITOR:
            if(DRV_FROM_AT(lchip))
            {
                CTC_ERROR_GOTO(MCHIP_PERI(lchip)->peri_get_sensor_monitor(lchip, (ctc_chip_sensor_monitor_t*)p_value), ret, error_roll_back);
            }
            else
            {
                PERI_UNLOCK(lchip);
                return CTC_E_NOT_SUPPORT;
            }
            break;
        default:
            PERI_UNLOCK(lchip);
            return CTC_E_INVALID_PARAM;
    }
    PERI_UNLOCK(lchip);

    return CTC_E_NONE;

error_roll_back:
    PERI_UNLOCK(lchip);

    return ret;
}

int32
sys_usw_get_chip_sensor(uint8 lchip, ctc_chip_sensor_type_t type, uint32* p_value)
{
    uint8 index = 0;
    ctc_chip_sensor_t sensor_value;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_value);
    SYS_PERI_INIT_CHECK(lchip);
    sal_memset(&sensor_value, 0, sizeof(sensor_value));
    sensor_value.type = type;
    if(NULL != MCHIP_PERI(lchip)->peri_get_chip_sensor)
    {
        PERI_LOCK(lchip);
        CTC_ERROR_RETURN_WITH_UNLOCK(MCHIP_PERI(lchip)->peri_get_chip_sensor(lchip, &sensor_value), p_usw_peri_master[lchip]->p_peri_mutex);
        PERI_UNLOCK(lchip);
    }

    if (DRV_FROM_TMM(lchip))
    {
        /*
        TsingMa_Mx: 4 temperature sensors, 6 voltage sensors;
        Arctic: 6 temperature sensors per core, 6 voltage sensors per core;
        */
        *p_value = sensor_value.value[0];
        for (index = 1; index < sensor_value.count; index++)
        {
            if (CTC_CHIP_SENSOR_TEMP == type)
            {
                *p_value = (sensor_value.value[index] >= *p_value)? sensor_value.value[index] : *p_value;
            }
            if (CTC_CHIP_SENSOR_VOLTAGE == type)
            {
                *p_value = (sensor_value.value[index] <= *p_value)? sensor_value.value[index] : *p_value;
            }
        }
    }
    else
    {
        /* Tsingma/Duet2 : 1 temperature sensor, 1 voltage sensor*/
        *p_value = sensor_value.value[0];
    }

    return CTC_E_NONE;
}

int32
sys_usw_peri_get_gport_by_mdio_para(uint8 lchip, uint8 bus, uint8 phy_addr, uint32* gport)
{
    uint8  gchip_id = 0;
    uint16 lport = 0;
    ctc_chip_phy_mapping_para_t* p_phy_mapping = NULL;
    int32 ret = CTC_E_NONE;

    p_phy_mapping = mem_malloc(MEM_SYSTEM_MODULE, sizeof(ctc_chip_phy_mapping_para_t));
    if (NULL == p_phy_mapping)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_phy_mapping, 0, sizeof(ctc_chip_phy_mapping_para_t));
    CTC_ERROR_GOTO(sys_usw_port_api_get_phy_mapping(lchip, p_phy_mapping), ret, out);
    CTC_ERROR_GOTO(sys_usw_get_gchip_id(lchip, &gchip_id), ret, out);

    for(lport=0; lport < SYS_PHY_PORT_NUM_PER_SLICE; lport++)
    {
        if ((bus == p_phy_mapping->port_mdio_mapping_tbl[lport])
                    && (phy_addr == p_phy_mapping->port_phy_mapping_tbl[lport]))
        {
            *gport = CTC_MAP_LPORT_TO_GPORT(gchip_id, lport);
            break;
        }
    }

    if(lport == SYS_PHY_PORT_NUM_PER_SLICE)
    {
        ret = CTC_E_INVALID_PARAM;
    }

out:
    if (p_phy_mapping)
    {
        mem_free(p_phy_mapping);
    }

    return ret;
}

int32
sys_usw_peri_phy_link_change_isr(uint8 lchip, uint32 intr, void * p_data)
{
    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_PTR_VALID_CHECK(p_data);
    SYS_PERI_INIT_CHECK(lchip);
    if(NULL != MCHIP_PERI(lchip)->peri_phy_link_change_isr)
    {
        CTC_ERROR_RETURN(MCHIP_PERI(lchip)->peri_phy_link_change_isr(lchip, intr, p_data));
    }
    return CTC_E_NONE;
}

int32
sys_usw_peri_gpio_isr(uint8 lchip, uint32 intr, void* p_data)
{
    CTC_INTERRUPT_EVENT_FUNC event_cb;
    uint32 cmd;
    uint32 gpio_status = 0;
    uint32 hs_gpio_status = 0;
    uint8  loop = 0;
    uint8  gchip_id = 0;
    uint8  gpio_isr_en = 0;
    uint8  gpio_id = 0;
    int32 ret = 0;
    ctc_chip_gpio_event_t   gpio_event_status;
    sys_intr_type_t    intr_type;
    uint32 value = 0;
    uint16 gpio_num = DRV_FROM_AT(lchip) ? SYS_PERI_GPIO_NUM_PER_CORE : SYS_PERI_HS_MAX_GPIO_ID;
    uint32 clear_tbl_id = 0, clear_field_id = 0;

    SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_interrupt_get_event_cb(lchip, CTC_EVENT_EXTRAL_GPIO_CHANGE, &event_cb));
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip_id));

    sal_memset(&gpio_event_status, 0, sizeof(ctc_chip_gpio_event_t));
    sal_memset(&intr_type, 0, sizeof(intr_type));
    intr_type.intr = intr;
    intr_type.sub_intr = INVG;
    intr_type.low_intr = INVG;
    CTC_ERROR_RETURN(sys_usw_interrupt_set_en(lchip, &intr_type, 0));

    cmd = DRV_IOR(GpioIntrStatus_t, GpioIntrStatus_gpioIntrStatus_f);
    DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &gpio_status);

    cmd = DRV_IOR(GpioHsIntrStatus_t, GpioHsIntrStatus_gpioHsIntrStatus_f);
    DRV_FIELD_IOCTL(lchip, 0, DRV_CMD_PP_EN(cmd), &hs_gpio_status);

    for(loop=0; loop < gpio_num; loop++)
    {
        if (SYS_PERI_GPIO_IS_HS(loop))
        {
            gpio_id = loop-SYS_PERI_MAX_GPIO_ID;
            gpio_isr_en = CTC_IS_BIT_SET(hs_gpio_status, gpio_id);
        }
        else
        {
            gpio_id = loop;
            gpio_isr_en = CTC_IS_BIT_SET(gpio_status, gpio_id);
        }

        if(gpio_isr_en)
        {
            /*clear status*/
            value = 0;
            clear_tbl_id = DRV_FROM_AT(lchip) ? GpioIntrClear_t : GpioEoiCtl_t;
            clear_field_id = DRV_FROM_AT(lchip) ? GpioIntrClear_cfgIntrClear_f : GpioEoiCtl_cfgIntrClear_f;
            CTC_BIT_SET(value, gpio_id);
            if (SYS_PERI_GPIO_IS_HS(loop))
            {
                cmd = DRV_IOW(GpioHsEoiCtl_t, GpioHsEoiCtl_cfgHsIntrClear_f);
                DRV_FIELD_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &value);
            }
            else
            {
                cmd = DRV_IOW(clear_tbl_id, clear_field_id);
                DRV_FIELD_IOCTL(lchip, loop, DRV_CMD_PP_EN(cmd), &value);
            }

            gpio_event_status.gpio_id = loop;
            SYS_PERI_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "gpio_id %d occur interrupt!\n",
                                                   loop);
            if(event_cb)
            {
                event_cb(gchip_id, &gpio_event_status);
            }
        }
    }

    sys_usw_interrupt_set_en(lchip, &intr_type, 1);
    return ret;
}

